-Copyright (c) 2009-2011 Bitcoin Developers
+Copyright (c) 2009-2012 Bitcoin Developers
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
TEMPLATE = app
TARGET =
-VERSION = 0.5.0
+VERSION = 0.5.0.6
INCLUDEPATH += src src/json src/qt
DEFINES += QT_GUI BOOST_THREAD_USE_LIB
CONFIG += no_include_pwd
contains(BITCOIN_NEED_QT_PLUGINS, 1) {
DEFINES += BITCOIN_NEED_QT_PLUGINS
- QTPLUGIN += qcncodecs qjpcodecs qtwcodecs qkrcodecs
+ QTPLUGIN += qcncodecs qjpcodecs qtwcodecs qkrcodecs qtaccessiblewidgets
}
!windows {
src/qt/bitcoinaddressvalidator.h \
src/base58.h \
src/bignum.h \
+ src/checkpoints.h \
src/util.h \
src/uint256.h \
src/serialize.h \
src/init.cpp \
src/net.cpp \
src/irc.cpp \
+ src/checkpoints.cpp \
src/db.cpp \
src/json/json_spirit_writer.cpp \
src/json/json_spirit_value.cpp \
TRANSLATIONS = $$files(src/qt/locale/bitcoin_*.ts)
isEmpty(QMAKE_LRELEASE) {
- win32:QMAKE_LRELEASE = $$[QT_INSTALL_BINS]\lrelease.exe
+ win32:QMAKE_LRELEASE = $$[QT_INSTALL_BINS]\\lrelease.exe
else:QMAKE_LRELEASE = $$[QT_INSTALL_BINS]/lrelease
}
isEmpty(TS_DIR):TS_DIR = src/qt/locale
macx:BOOST_INCLUDE_PATH = /opt/local/include
}
-windows:LIBS += -lws2_32 -lgdi32
+windows:LIBS += -lws2_32
windows:DEFINES += WIN32
windows:RC_FILE = src/qt/res/bitcoin-qt.rc
+windows:!contains(MINGW_THREAD_BUGFIX, 0) {
+ # At least qmake's win32-g++-cross profile is missing the -lmingwthrd
+ # thread-safety flag. GCC has -mthreads to enable this, but it doesn't
+ # work with static linking. -lmingwthrd must come BEFORE -lmingw, so
+ # it is prepended to QMAKE_LIBS_QT_ENTRY.
+ # It can be turned off with MINGW_THREAD_BUGFIX=0, just in case it causes
+ # any problems on some untested qmake profile now or in the future.
+ DEFINES += _MT
+ QMAKE_LIBS_QT_ENTRY = -lmingwthrd $$QMAKE_LIBS_QT_ENTRY
+}
+
macx:HEADERS += src/qt/macdockiconhandler.h
macx:OBJECTIVE_SOURCES += src/qt/macdockiconhandler.mm
macx:LIBS += -framework Foundation -framework ApplicationServices -framework AppKit
INCLUDEPATH += $$BOOST_INCLUDE_PATH $$BDB_INCLUDE_PATH $$OPENSSL_INCLUDE_PATH
LIBS += $$join(BOOST_LIB_PATH,,-L,) $$join(BDB_LIB_PATH,,-L,) $$join(OPENSSL_LIB_PATH,,-L,)
LIBS += -lssl -lcrypto -ldb_cxx$$BDB_LIB_SUFFIX
+# -lgdi32 has to happen after -lcrypto (see #681)
+windows:LIBS += -lgdi32
LIBS += -lboost_system$$BOOST_LIB_SUFFIX -lboost_filesystem$$BOOST_LIB_SUFFIX -lboost_program_options$$BOOST_LIB_SUFFIX -lboost_thread$$BOOST_THREAD_LIB_SUFFIX
contains(RELEASE, 1) {
+bitcoin (0.5.0.4-natty0) natty; urgency=low
+
+ * New upstream release.
+
+ -- Matt Corallo <matt@bluematt.me> Tue, 10 Jan 2012 15:53:00 -0500
+
+bitcoin (0.5.0.3-natty1) natty; urgency=low
+
+ * Remove mentions on anonymity in package descriptions and manpage.
+ These should never have been there, bitcoin isnt anonymous without
+ a ton of work that virtually no users will ever be willing and
+ capable of doing
+
+ -- Matt Corallo <matt@bluematt.me> Sat, 7 Jan 2012 13:37:00 -0500
+
+bitcoin (0.5.0.3-natty0) natty; urgency=low
+
+ * New upstream release.
+
+ -- Matt Corallo <matt@bluematt.me> Fri, 16 Dec 2011 13:27:00 -0500
+
+bitcoin (0.5.0-natty0) natty; urgency=low
+
+ * New upstream release.
+
+ -- Matt Corallo <matt@bluematt.me> Mon, 21 Nov 2011 11:32:00 -0500
+
+bitcoin (0.5.0~rc7-natty0) natty; urgency=low
+
+ * New upstream release candidate.
+
+ -- Matt Corallo <matt@bluematt.me> Sun, 20 Nov 2011 17:08:00 -0500
+
bitcoin (0.5.0~rc3-natty0) natty; urgency=low
* New upstream release candidate.
Package: bitcoind
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}
-Description: peer-to-peer network based anonymous digital currency - daemon
+Description: peer-to-peer network based digital currency - daemon
Bitcoin is a free open source peer-to-peer electronic cash system that
is completely decentralized, without the need for a central server or
trusted parties. Users hold the crypto keys to their own money and
Package: bitcoin-qt
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}
-Description: peer-to-peer network based anonymous digital currency - QT GUI
+Description: peer-to-peer network based digital currency - QT GUI
Bitcoin is a free open source peer-to-peer electronic cash system that
is completely decentralized, without the need for a central server or
trusted parties. Users hold the crypto keys to their own money and
Files: src/qt/res/icons/clock*.png, src/qt/res/icons/tx*.png,
src/qt/res/src/*.svg
Copyright: Wladimir van der Laan
-License: CC-BY-3
+License: Expat
Files: src/qt/res/icons/address-book.png, src/qt/res/icons/export.png,
src/qt/res/icons/history.png, src/qt/res/icons/key.png,
You should have received a copy of the GNU General Public License along
with this program. If not, see <http://www.gnu.org/licenses/>.
-License: CC-BY-3
- This work is licensed under a Creative Commons Attribution 3.0 Unported
- License.
-Comment:
- You can get a full copy of the license at
- <http://creativecommons.org/licenses/by/3.0/>.
-
License: LGPL
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
.TH BITCOIND "1" "January 2011" "bitcoind 3.19"
.SH NAME
-bitcoind \- peer-to-peer network based anonymous digital currency
+bitcoind \- peer-to-peer network based digital currency
.SH SYNOPSIS
bitcoin [options] <command> [params]
.TP
- "wine"
reference_datetime: "2011-01-30 00:00:00"
remotes:
-- "url": "https://github.com/bitcoin/bitcoin.git"
+- "url": "https://git.gitorious.org/+bitcoin-stable-developers/bitcoin/bitcoind-stable.git"
"dir": "bitcoin"
files:
- "qt-win32-4.7.4-gitian.zip"
export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1
export FAKETIME=$REFERENCE_DATETIME
export TZ=UTC
- $HOME/qt/src/bin/qmake -spec unsupported/win32-g++-cross MINIUPNPC_LIB_PATH=$HOME/build/miniupnpc MINIUPNPC_INCLUDE_PATH=$HOME/build/ BDB_LIB_PATH=$HOME/build/db-4.8.30.NC/build_unix BDB_INCLUDE_PATH=$HOME/build/db-4.8.30.NC/build_unix BOOST_LIB_PATH=$HOME/build/boost_1_47_0/stage/lib BOOST_INCLUDE_PATH=$HOME/build/boost_1_47_0 BOOST_LIB_SUFFIX=-mt-s BOOST_THREAD_LIB_SUFFIX=_win32-mt-s OPENSSL_LIB_PATH=$HOME/build/openssl-1.0.0e OPENSSL_INCLUDE_PATH=$HOME/build/openssl-1.0.0e/include INCLUDEPATH=$HOME/build DEFINES=BOOST_THREAD_USE_LIB BITCOIN_NEED_QT_PLUGINS=1 QMAKE_LRELEASE=lrelease QMAKE_CXXFLAGS=-frandom-seed=bitcoin QMAKE_LFLAGS=-frandom-seed=bitcoin
+ $HOME/qt/src/bin/qmake -spec unsupported/win32-g++-cross USE_SSL=1 MINIUPNPC_LIB_PATH=$HOME/build/miniupnpc MINIUPNPC_INCLUDE_PATH=$HOME/build/ BDB_LIB_PATH=$HOME/build/db-4.8.30.NC/build_unix BDB_INCLUDE_PATH=$HOME/build/db-4.8.30.NC/build_unix BOOST_LIB_PATH=$HOME/build/boost_1_47_0/stage/lib BOOST_INCLUDE_PATH=$HOME/build/boost_1_47_0 BOOST_LIB_SUFFIX=-mt-s BOOST_THREAD_LIB_SUFFIX=_win32-mt-s OPENSSL_LIB_PATH=$HOME/build/openssl-1.0.0e OPENSSL_INCLUDE_PATH=$HOME/build/openssl-1.0.0e/include INCLUDEPATH=$HOME/build DEFINES=BOOST_THREAD_USE_LIB BITCOIN_NEED_QT_PLUGINS=1 QMAKE_LRELEASE=lrelease QMAKE_CXXFLAGS=-frandom-seed=bitcoin QMAKE_LFLAGS=-frandom-seed=bitcoin
make $MAKEOPTS
cp release/bitcoin-qt.exe $OUTDIR/
#
export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1
export FAKETIME=$REFERENCE_DATETIME
export TZ=UTC
- make -f makefile.linux-mingw $MAKEOPTS DEPSDIR=$HOME/build bitcoind.exe USE_UPNP=0
+ make -f makefile.linux-mingw $MAKEOPTS DEPSDIR=$HOME/build bitcoind.exe USE_SSL=1 USE_UPNP=0
i586-mingw32msvc-strip bitcoind.exe
makensis ../share/setup.nsi
cp ../share/bitcoin-*-win32-setup.exe $OUTDIR/
- "unzip"
reference_datetime: "2011-01-30 00:00:00"
remotes:
-- "url": "https://github.com/bitcoin/bitcoin.git"
+- "url": "https://git.gitorious.org/+bitcoin-stable-developers/bitcoin/bitcoind-stable.git"
"dir": "bitcoin"
files:
- "miniupnpc-1.6.tar.gz"
cp $OUTDIR/src/COPYING $OUTDIR
cd src
sed 's/$(DEBUGFLAGS)//' -i makefile.unix
- make -f makefile.unix STATIC=1 DEFS="-I$INSTDIR/include -L$INSTDIR/lib" $MAKEOPTS bitcoind USE_UPNP=0
+ make -f makefile.unix STATIC=1 OPENSSL_INCLUDE_PATH="$INSTDIR/include" OPENSSL_LIB_PATH="$INSTDIR/lib" $MAKEOPTS bitcoind USE_UPNP=0 USE_SSL=1
mkdir -p $OUTDIR/bin/$GBUILD_BITS
install -s bitcoind $OUTDIR/bin/$GBUILD_BITS
cd ..
- qmake INCLUDEPATH="$INSTDIR/include" LIBS="-L$INSTDIR/lib" RELEASE=1
+ qmake INCLUDEPATH="$INSTDIR/include" LIBS="-L$INSTDIR/lib" RELEASE=1 USE_SSL=1
make $MAKEOPTS
install bitcoin-qt $OUTDIR/bin/$GBUILD_BITS
--- /dev/null
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: SKS 1.1.0
+
+mQENBE5UtMEBCADOUz2i9l/D8xYINCmfUDnxi+DXvX5LmZ39ZdvsoE+ugO0SRRGdIHEFO2is
+0xezX50wXu9aneb+tEqM0BuiLo6VxaXpxrkxHpr6c4jf37SkE/H0qsi/txEUp7337y3+4HMG
+lUjiuh802I72p1qusjsKBnmnnR0rwNouTcoDmGUDh7jpKCtzFv+2TR2dRthJn7vmmjq3+bG6
+PYfqoFY1yHrAGT1lrDBULZsQ/NBLI2+J4oo2LYv3GCq8GNnzrovqvTvui50VSROhLrOe58o2
+shE+sjQShAy5wYkPt1R1fQnpfx+5vf+TPnkxVwRb3h5GhCp0YL8XC/BXsd5vM4KlVH2rABEB
+AAG0K1dsYWRpbWlyIEouIHZhbiBkZXIgTGFhbiA8bGFhbndqQGdtYWlsLmNvbT6JATgEEwEC
+ACIFAk5UtMECGwMGCwkIBwMCBhUIAgkKCwQWAgMBAh4BAheAAAoJEHSBCwEjRsmmy6YIAK09
+buNXyYQrJBsX16sXxEhx5QPKyF3uHJDFJv66SdnpvIkNoznsaPiRJkbTANop93FZmaGa6wVn
+zGDiz7jPA8Dpxx5aAYPhIT+zPJAdXWM3wJ/Gio9besRNzniai8Lwi5MZ9R/5yFGBobm6/AcN
+4sUoqA3NSV2U3I29R0Vwlzo8GVtmyi9ENSi6Oo7AcXNTRt69cxW4nAHkB+amwwDJlcAb31ex
+bogYXPhScwqQZixRr+JBkKxBjkTXXnQypT4KI5SegYwQVYfyiZmDP7UHKe/u6pSKKbVphLg8
+xLB5spcXse8/a2+onrbNlw6y8TXiJ++Z54PE7zztWTXf2huakeG5AQ0ETlS0wQEIAMNO3OkP
+xoPRKWzBLcI7JRITAW+HNaLTq3uN2+4WxA57DEjbL9EDoAv+7wTkDAL40f0T+xiu6GJcLFjw
+GJZu/tYu7+mErHjrdo+K4suCQt7w5EXCBvOLjhW4tyYMzNx8hP+oqzOW9iEC+6VV91+DYeqt
+EkJuyVXOI4vzBlTw8uGow8aMMsCq8XVvKUZFTPsjGl197Q5B3A+ZOFCR8xqiqdPjuz6MglVV
+oFdDNu3EZn8zkGsQlovXoE9ndVeVzx/XMNmsxFaMYsReUs253RIf1FEfgExID0fg2OnyLCjS
+2iFW1RgajS+/saIkKl+N1iuMzJA7wMAM0plhRueOG0MtZSsAEQEAAYkBHwQYAQIACQUCTlS0
+wQIbDAAKCRB0gQsBI0bJpmsDB/4waenn2CvSHXyomykfpwf5lMte1V5LvH3z5R2LY+1NopRv
+LSz3iC39x69XWiTbhywDfgafnGPW4pWBOff2/bu5/A6z1Hnan1vyrRRD/hx1uMJ7S6q+bIvZ
+iVIg1p0jH6tdIIhwX3cydhdRZHo7e9oSMgOUWsr6Ar59NRo9CENwGPE4U61HXfOnxWdrFWoA
+XdwZczBeLxmUy6Vo6sKqv+gE4bqrtAM0sY/MsQ9cU95x+52ox/sq44lQMwd3ZBYUP7B1qbHI
+hZSZuch6MLi5scLPeau0ZvCaljiaMeivP5+x0gWPRs0kI+9sZxInbqvrsJ6oOBJM3xYGhtn1
+zZ7qmZR7
+=si/k
+-----END PGP PUBLIC KEY BLOCK-----
weight: 40
name: Devrandom
key: devrandom
+ E463A93F5F3117EEDE6C7316BD02942421F4889F:
+ weight: 40
+ name: Luke-Jr
+ key: luke-jr
D762373D24904A3E42F33B08B9A408E71DAAC974:
weight: 40
- name: Sipa
+ name: "Pieter Wuille"
key: sipa
77E72E69DA7EE0A148C06B21B34821D4944DE5F7:
weight: 40
weight: 40
name: "Gavin Andresen"
key: gavinandresen
+ 71A3B16735405025D447E8F274810B012346C9A6
+ weight: 40
+ name: "Wladimir J. van der Laan"
+ key: laanwj
minimum_weight: 120
weight: 40
name: Devrandom
key: devrandom
+ E463A93F5F3117EEDE6C7316BD02942421F4889F:
+ weight: 40
+ name: Luke-Jr
+ key: luke-jr
D762373D24904A3E42F33B08B9A408E71DAAC974:
weight: 40
- name: Sipa
+ name: "Pieter Wuille"
key: sipa
77E72E69DA7EE0A148C06B21B34821D4944DE5F7:
weight: 40
weight: 40
name: "Gavin Andresen"
key: gavinandresen
+ 71A3B16735405025D447E8F274810B012346C9A6
+ weight: 40
+ name: "Wladimir J. van der Laan"
+ key: laanwj
minimum_weight: 120
-Bitcoin 0.5.0 BETA
+Bitcoin 0.5.0.6 BETA
-Copyright (c) 2009-2011 Bitcoin Developers
+Copyright (c) 2009-2012 Bitcoin Developers
Distributed under the MIT/X11 software license, see the accompanying
file license.txt or http://www.opensource.org/licenses/mit-license.php.
This product includes software developed by the OpenSSL Project for use in
-Bitcoin 0.5.0 BETA\r
+Bitcoin 0.5.0.6 BETA\r
\r
-Copyright (c) 2009-2011 Bitcoin Developers\r
+Copyright (c) 2009-2012 Bitcoin Developers\r
Distributed under the MIT/X11 software license, see the accompanying\r
file license.txt or http://www.opensource.org/licenses/mit-license.php.\r
This product includes software developed by the OpenSSL Project for use in\r
Icon: src/qt/res/icons/clock*.png, src/qt/res/icons/tx*.png,
src/qt/res/src/*.svg
Designer: Wladimir van der Laan
-License: Creative Commons Attribution
+License: MIT
Icon: src/qt/res/icons/address-book.png, src/qt/res/icons/export.png,
src/qt/res/icons/history.png, src/qt/res/icons/key.png,
+* update translations (ping tcatm on IRC for now)
+
* update (commit) version in sources
+ bitcoin-qt.pro
src/serialize.h
share/setup.nsi
-
-* update (commit) version in OSX app bundle
- contrib/Bitcoin.app/Contents/Info.plist
-
- * CFBundleShortVersionString should have value like 0.5.0
- * CFBundleVersion should have value like 500
+ doc/README*
* tag version in git
- git tag -a v0.5.0
+ git tag -a v0.5.1
* write release notes. git shortlog helps a lot:
- git shortlog --no-merges v0.4.0..
-
-* create source-only archive
-
- git archive --format=tar --prefix=bitcoin-0.5.0/ HEAD | \
- gzip -9c > ~/tmp/bitcoin-0.5.0-src.tar.gz
+ git shortlog --no-merges v0.5.0..
* perform gitian builds
* From a directory containing the bitcoin source, gitian-builder and gitian.sigs
export SIGNER=(your gitian key, ie bluematt, sipa, etc)
- export VERSION=0.5.0
+ export VERSION=0.5.1
cd ./gitian-builder
* Fetch and build inputs:
cp build/out/qt-win32-4.7.4-gitian.zip inputs/
* Build bitcoind and bitcoin-qt on Linux32, Linux64, and Win32:
- ./bin/gbuild --commit bitcoin=v$VERSION ../bitcoin/contrib/gitian-descriptors/gitian.yml
- ./bin/gsign --signer $SIGNER --release $VERSION --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian.yml
+ ./bin/gbuild --commit bitcoin=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian.yml
+ ./bin/gsign --signer $SIGNER --release ${VERSION} --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian.yml
pushd build/out
- zip -r bitcoin-$VERSION-linux-gitian.zip *
- mv bitcoin-$VERSION-linux-gitian.zip ../../
+ zip -r bitcoin-${VERSION}-linux-gitian.zip *
+ mv bitcoin-${VERSION}-linux-gitian.zip ../../
popd
- ./bin/gbuild --commit bitcoin=v$VERSION ../bitcoin/contrib/gitian-descriptors/gitian-win32.yml
- ./bin/gsign --signer $SIGNER --release $VERSION-win32 --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian-win32.yml
+ ./bin/gbuild --commit bitcoin=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian-win32.yml
+ ./bin/gsign --signer $SIGNER --release ${VERSION}-win32 --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian-win32.yml
pushd build/out
- zip -r bitcoin-$VERSION-win32-gitian.zip *
- mv bitcoin-$VERSION-win32-gitian.zip ../../
+ zip -r bitcoin-${VERSION}-win32-gitian.zip *
+ mv bitcoin-${VERSION}-win32-gitian.zip ../../
popd
Build output expected:
- 1. linux 32-bit and 64-bit binaries + source (bitcoin-$VERSION-linux-gitian.zip)
- 2. windows 32-bit binary, installer + source (bitcoin-$VERSION-win32-gitian.zip)
- 3. Gitian signatures (in gitian.sigs/$VERSION[-win32]/(your gitian key)/
+ 1. linux 32-bit and 64-bit binaries + source (bitcoin-${VERSION}-linux-gitian.zip)
+ 2. windows 32-bit binary, installer + source (bitcoin-${VERSION}-win32-gitian.zip)
+ 3. Gitian signatures (in gitian.sigs/${VERSION}[-win32]/(your gitian key)/
* repackage gitian builds for release as stand-alone zip/tar/installer exe
* Linux .tar.gz:
- unzip bitcoin-$VERSION-linux-gitian.zip -d bitcoin-$VERSION-linux
- tar czvf bitcoin-$VERSION-linux.tar.gz bitcoin-$VERSION-linux
- rm -rf bitcoin-$VERSION-linux
+ unzip bitcoin-${VERSION}-linux-gitian.zip -d bitcoin-${VERSION}-linux
+ tar czvf bitcoin-${VERSION}-linux.tar.gz bitcoin-${VERSION}-linux
+ rm -rf bitcoin-${VERSION}-linux
* Windows .zip and setup.exe:
- unzip bitcoin-$VERSION-win32-gitian.zip -d bitcoin-$VERSION-win32
- mv bitcoin-$VERSION-win32/bitcoin-*-setup.exe .
- zip -r bitcoin-$VERSION-win32.zip bitcoin-$VERSION-win32
- rm -rf bitcoin-$VERSION-win32
+ unzip bitcoin-${VERSION}-win32-gitian.zip -d bitcoin-${VERSION}-win32
+ mv bitcoin-${VERSION}-win32/bitcoin-*-setup.exe .
+ zip -r bitcoin-${VERSION}-win32.zip bitcoin-${VERSION}-win32
+ rm -rf bitcoin-${VERSION}-win32
* perform Mac build
See this blog post for how Gavin set up his build environment and
Build output expected:
Bitcoin-Qt.dmg
-* upload source and builds to SourceForge
+* upload builds to SourceForge
-* create SHA1SUMS for builds, and PGP-sign it
+* create SHA256SUMS for builds, and PGP-sign it
* update bitcoin.org version
* update forum version
-* update wiki
-
* update wiki download links
-* release gitian-signed gitian archives
+* Commit your signature to gitian.sigs:
+ pushd gitian.sigs
+ git add ${VERSION}/${SIGNER}
+ git add ${VERSION}-win32/${SIGNER}
+ git commit -a
+ git push # Assuming you can push to the gitian.sigs tree
+ popd
+
+-------------------------------------------------------------------------
- * Collect enough gitian signatures to meet minimum_weight (see contrib/gitian-downloader/*-download-config)
+* After 3 or more people have gitian-built, repackage gitian-signed zips:
* From a directory containing bitcoin source, gitian.sigs and gitian zips
- export VERSION=0.5.0
- mkdir bitcoin-$VERSION-linux-gitian; cd bitcoin-$VERSION-linux-gitian
- unzip ../bitcoin-$VERSION-linux-gitian.zip
+ export VERSION=0.5.1
+ mkdir bitcoin-${VERSION}-linux-gitian
+ pushd bitcoin-${VERSION}-linux-gitian
+ unzip ../bitcoin-${VERSION}-linux-gitian.zip
mkdir gitian
cp ../bitcoin/contrib/gitian-downloader/*.pgp ./gitian/
- for file in `ls ../gitian.sigs/$VERSION/`; do
- cp ../gitian.sigs/$VERSION/$file/bitcoin-build.assert ./gitian/$file-build.assert
- cp ../gitian.sigs/$VERSION/$file/bitcoin-build.assert.sig ./gitian/$file-build.assert.sig
+ for signer in $(ls ../gitian.sigs/${VERSION}/); do
+ cp ../gitian.sigs/${VERSION}/${signer}/bitcoin-build.assert ./gitian/${signer}-build.assert
+ cp ../gitian.sigs/${VERSION}/${signer}/bitcoin-build.assert.sig ./gitian/${signer}-build.assert.sig
done
- zip -r bitcoin-$VERSION-linux-gitian.zip *
- cp bitcoin-$VERSION-linux-gitian.zip ../
- cd ..
- mkdir bitcoin-$VERSION-linux-gitian; cd bitcoin-$VERSION-linux-gitian
- unzip ../bitcoin-$VERSION-linux-gitian.zip
+ zip -r bitcoin-${VERSION}-linux-gitian.zip *
+ cp bitcoin-${VERSION}-linux-gitian.zip ../
+ popd
+ mkdir bitcoin-${VERSION}-win32-gitian
+ pushd bitcoin-${VERSION}-win32-gitian
+ unzip ../bitcoin-${VERSION}-win32-gitian.zip
mkdir gitian
cp ../bitcoin/contrib/gitian-downloader/*.pgp ./gitian/
- for file in `ls ../gitian.sigs/$VERSION/`; do
- cp ../gitian.sigs/$VERSION/$file/bitcoin-build.assert ./gitian/$file-build.assert
- cp ../gitian.sigs/$VERSION/$file/bitcoin-build.assert.sig ./gitian/$file-build.assert.sig
+ for signer in $(ls ../gitian.sigs/${VERSION}-win32/); do
+ cp ../gitian.sigs/${VERSION}-win32/${signer}/bitcoin-build.assert ./gitian/${signer}-build.assert
+ cp ../gitian.sigs/${VERSION}-win32/${signer}/bitcoin-build.assert.sig ./gitian/${signer}-build.assert.sig
done
- zip -r bitcoin-$VERSION-linux-gitian.zip *
- cp bitcoin-$VERSION-linux-gitian.zip ../
+ zip -r bitcoin-${VERSION}-win32-gitian.zip *
+ cp bitcoin-${VERSION}-win32-gitian.zip ../
+ popd
* Upload gitian zips to SourceForge
Translations
============
-The QT GUI can be easily be translated into other languages. Here's how we
+The Qt GUI can be easily translated into other languages. Here's how we
handle those translations.
Files and Folders
#### Source file
-`src/qt/locale/bitcoin_en.ts` is a treated in a special way. It is used as the
-source for all other translations. Whenever a string in the code is change
+`src/qt/locale/bitcoin_en.ts` is treated in a special way. It is used as the
+source for all other translations. Whenever a string in the code is changed
this file must be updated to reflect those changes. Usually, this can be
-accomplished by running `lupdate`
+accomplished by running `lupdate`.
Syncing with transifex
----------------------
https://www.transifex.net/projects/p/bitcoin/resource/tx/
-The "transifex client":http://help.transifex.net/features/client/index.html
-will help with fetching new translations from transifex.
-
+The "transifex client" (see: http://help.transifex.net/features/client/)
+will help with fetching new translations from transifex. Use the following
+config to be able to connect with the client.
### .tx/config
\r
# General Symbol Definitions\r
!define REGKEY "SOFTWARE\$(^Name)"\r
-!define VERSION 0.5.0\r
+!define VERSION 0.5.0.6\r
!define COMPANY "Bitcoin project"\r
!define URL http://www.bitcoin.org/\r
\r
!insertmacro MUI_LANGUAGE English\r
\r
# Installer attributes\r
-OutFile bitcoin-0.5.0-win32-setup.exe\r
+OutFile bitcoin-0.5.0.6-win32-setup.exe\r
InstallDir $PROGRAMFILES\Bitcoin\r
CRCCheck on\r
XPStyle on\r
BrandingText " "\r
ShowInstDetails show\r
-VIProductVersion 0.5.0.0\r
+VIProductVersion 0.5.0.6\r
VIAddVersionKey ProductName Bitcoin\r
VIAddVersionKey ProductVersion "${VERSION}"\r
VIAddVersionKey CompanyName "${COMPANY}"\r
File /r /x *.exe /x *.o ../src\*.*\r
SetOutPath $INSTDIR\r
WriteRegStr HKCU "${REGKEY}\Components" Main 1\r
+\r
+ # Remove old wxwidgets-based-bitcoin executable and locales:\r
+ Delete /REBOOTOK $INSTDIR\bitcoin.exe\r
+ RMDir /r /REBOOTOK $INSTDIR\locale\r
SectionEnd\r
\r
Section -post SEC0001\r
std::vector<unsigned char> getvch() const
{
unsigned int nSize = BN_bn2mpi(this, NULL);
- if (nSize < 4)
+ if (nSize <= 4)
return std::vector<unsigned char>();
std::vector<unsigned char> vch(nSize);
BN_bn2mpi(this, &vch[0]);
// Copyright (c) 2010 Satoshi Nakamoto
-// Copyright (c) 2011 The Bitcoin developers
+// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
obj.push_back(Pair("keypoolsize", pwalletMain->GetKeyPoolSize()));
obj.push_back(Pair("paytxfee", ValueFromAmount(nTransactionFee)));
if (pwalletMain->IsCrypted())
- obj.push_back(Pair("unlocked_until", (boost::int64_t)nWalletUnlockTime));
+ obj.push_back(Pair("unlocked_until", (boost::int64_t)nWalletUnlockTime / 1000));
obj.push_back(Pair("errors", GetWarnings("statusbar")));
return obj;
}
CBlockIndex *block;
for (block = pindexBest;
block && block->nHeight > target_height;
- block = block->pprev);
+ block = block->pprev) { }
lastblock = block ? block->GetBlockHash() : 0;
}
void ThreadCleanWalletPassphrase(void* parg)
{
- int64 nMyWakeTime = GetTime() + *((int*)parg);
+ int64 nMyWakeTime = GetTimeMillis() + *((int64*)parg) * 1000;
+
+ ENTER_CRITICAL_SECTION(cs_nWalletUnlockTime);
if (nWalletUnlockTime == 0)
{
- CRITICAL_BLOCK(cs_nWalletUnlockTime)
+ nWalletUnlockTime = nMyWakeTime;
+
+ do
{
- nWalletUnlockTime = nMyWakeTime;
- }
+ if (nWalletUnlockTime==0)
+ break;
+ int64 nToSleep = nWalletUnlockTime - GetTimeMillis();
+ if (nToSleep <= 0)
+ break;
- while (GetTime() < nWalletUnlockTime)
- Sleep(GetTime() - nWalletUnlockTime);
+ LEAVE_CRITICAL_SECTION(cs_nWalletUnlockTime);
+ Sleep(nToSleep);
+ ENTER_CRITICAL_SECTION(cs_nWalletUnlockTime);
- CRITICAL_BLOCK(cs_nWalletUnlockTime)
+ } while(1);
+
+ if (nWalletUnlockTime)
{
nWalletUnlockTime = 0;
+ pwalletMain->Lock();
}
}
else
{
- CRITICAL_BLOCK(cs_nWalletUnlockTime)
- {
- if (nWalletUnlockTime < nMyWakeTime)
- nWalletUnlockTime = nMyWakeTime;
- }
- free(parg);
- return;
+ if (nWalletUnlockTime < nMyWakeTime)
+ nWalletUnlockTime = nMyWakeTime;
}
- pwalletMain->Lock();
+ LEAVE_CRITICAL_SECTION(cs_nWalletUnlockTime);
- delete (int*)parg;
+ delete (int64*)parg;
}
Value walletpassphrase(const Array& params, bool fHelp)
throw JSONRPCError(-17, "Error: Wallet is already unlocked.");
// Note that the walletpassphrase is stored in params[0] which is not mlock()ed
- string strWalletPass;
+ SecureString strWalletPass;
strWalletPass.reserve(100);
- mlock(&strWalletPass[0], strWalletPass.capacity());
- strWalletPass = params[0].get_str();
+ // TODO: get rid of this .c_str() by implementing SecureString::operator=(std::string)
+ // Alternately, find a way to make params[0] mlock()'d to begin with.
+ strWalletPass = params[0].get_str().c_str();
if (strWalletPass.length() > 0)
{
if (!pwalletMain->Unlock(strWalletPass))
- {
- fill(strWalletPass.begin(), strWalletPass.end(), '\0');
- munlock(&strWalletPass[0], strWalletPass.capacity());
throw JSONRPCError(-14, "Error: The wallet passphrase entered was incorrect.");
- }
- fill(strWalletPass.begin(), strWalletPass.end(), '\0');
- munlock(&strWalletPass[0], strWalletPass.capacity());
}
else
throw runtime_error(
"Stores the wallet decryption key in memory for <timeout> seconds.");
CreateThread(ThreadTopUpKeyPool, NULL);
- int* pnSleepTime = new int(params[1].get_int());
+ int64* pnSleepTime = new int64(params[1].get_int64());
CreateThread(ThreadCleanWalletPassphrase, pnSleepTime);
return Value::null;
if (!pwalletMain->IsCrypted())
throw JSONRPCError(-15, "Error: running with an unencrypted wallet, but walletpassphrasechange was called.");
- string strOldWalletPass;
+ // TODO: get rid of these .c_str() calls by implementing SecureString::operator=(std::string)
+ // Alternately, find a way to make params[0] mlock()'d to begin with.
+ SecureString strOldWalletPass;
strOldWalletPass.reserve(100);
- mlock(&strOldWalletPass[0], strOldWalletPass.capacity());
- strOldWalletPass = params[0].get_str();
+ strOldWalletPass = params[0].get_str().c_str();
- string strNewWalletPass;
+ SecureString strNewWalletPass;
strNewWalletPass.reserve(100);
- mlock(&strNewWalletPass[0], strNewWalletPass.capacity());
- strNewWalletPass = params[1].get_str();
+ strNewWalletPass = params[1].get_str().c_str();
if (strOldWalletPass.length() < 1 || strNewWalletPass.length() < 1)
throw runtime_error(
"Changes the wallet passphrase from <oldpassphrase> to <newpassphrase>.");
if (!pwalletMain->ChangeWalletPassphrase(strOldWalletPass, strNewWalletPass))
- {
- fill(strOldWalletPass.begin(), strOldWalletPass.end(), '\0');
- fill(strNewWalletPass.begin(), strNewWalletPass.end(), '\0');
- munlock(&strOldWalletPass[0], strOldWalletPass.capacity());
- munlock(&strNewWalletPass[0], strNewWalletPass.capacity());
throw JSONRPCError(-14, "Error: The wallet passphrase entered was incorrect.");
- }
- fill(strNewWalletPass.begin(), strNewWalletPass.end(), '\0');
- fill(strOldWalletPass.begin(), strOldWalletPass.end(), '\0');
- munlock(&strOldWalletPass[0], strOldWalletPass.capacity());
- munlock(&strNewWalletPass[0], strNewWalletPass.capacity());
return Value::null;
}
if (!pwalletMain->IsCrypted())
throw JSONRPCError(-15, "Error: running with an unencrypted wallet, but walletlock was called.");
- pwalletMain->Lock();
CRITICAL_BLOCK(cs_nWalletUnlockTime)
{
+ pwalletMain->Lock();
nWalletUnlockTime = 0;
}
throw runtime_error("Not Yet Implemented: use GUI to encrypt wallet, not RPC command");
#endif
- string strWalletPass;
+ // TODO: get rid of this .c_str() by implementing SecureString::operator=(std::string)
+ // Alternately, find a way to make params[0] mlock()'d to begin with.
+ SecureString strWalletPass;
strWalletPass.reserve(100);
- mlock(&strWalletPass[0], strWalletPass.capacity());
- strWalletPass = params[0].get_str();
+ strWalletPass = params[0].get_str().c_str();
if (strWalletPass.length() < 1)
throw runtime_error(
"Encrypts the wallet with <passphrase>.");
if (!pwalletMain->EncryptWallet(strWalletPass))
- {
- fill(strWalletPass.begin(), strWalletPass.end(), '\0');
- munlock(&strWalletPass[0], strWalletPass.capacity());
throw JSONRPCError(-16, "Error: Failed to encrypt the wallet.");
- }
- fill(strWalletPass.begin(), strWalletPass.end(), '\0');
- munlock(&strWalletPass[0], strWalletPass.capacity());
// BDB seems to have a bad habit of writing old data into
// slack space in .dat files; that is bad if the old data is
}
// Update nTime
- pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
+ pblock->UpdateTime(pindexPrev);
pblock->nNonce = 0;
// Update nExtraNonce
}
// Update nTime
- pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
+ pblock->UpdateTime(pindexPrev);
pblock->nNonce = 0;
Array transactions;
if (mapArgs["-rpcuser"] == "" && mapArgs["-rpcpassword"] == "")
{
+ unsigned char rand_pwd[32];
+ RAND_bytes(rand_pwd, 32);
string strWhatAmI = "To use bitcoind";
if (mapArgs.count("-server"))
strWhatAmI = strprintf(_("To use the %s option"), "\"-server\"");
else if (mapArgs.count("-daemon"))
strWhatAmI = strprintf(_("To use the %s option"), "\"-daemon\"");
- PrintConsole(
- _("Error: %s, you must set rpcpassword=<password>\nin the configuration file: %s\n"
+ ThreadSafeMessageBox(strprintf(
+ _("Error: %s, you must set a 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"
"If the file does not exist, create it with owner-readable-only file permissions.\n"),
strWhatAmI.c_str(),
- GetConfigFile().c_str());
+ GetConfigFile().c_str(),
+ EncodeBase58(&rand_pwd[0],&rand_pwd[0]+32).c_str()),
+ _("Error"), wxOK | wxMODAL);
#ifndef QT_GUI
CreateThread(Shutdown, NULL);
#endif
}
if (!HTTPAuthorized(mapHeaders))
{
- // Deter brute-forcing short passwords
- if (mapArgs["-rpcpassword"].size() < 15)
- Sleep(50);
+ printf("ThreadRPCServer incorrect password attempt from %s\n",peer.address().to_string().c_str());
+ /* Deter brute-forcing short passwords.
+ If this results in a DOS the user really
+ shouldn't have their RPC port exposed.*/
+ if (mapArgs["-rpcpassword"].size() < 20)
+ Sleep(250);
stream << HTTPReply(401, "") << std::flush;
- printf("ThreadRPCServer incorrect password attempt\n");
continue;
}
--- /dev/null
+// Copyright (c) 2009-2012 The Bitcoin developers
+// Distributed under the MIT/X11 software license, see the accompanying
+// file license.txt or http://www.opensource.org/licenses/mit-license.php.
+
+#include <boost/assign/list_of.hpp> // for 'map_list_of()'
+#include <boost/foreach.hpp>
+
+#include "headers.h"
+#include "checkpoints.h"
+
+namespace Checkpoints
+{
+ typedef std::map<int, uint256> MapCheckpoints;
+
+ //
+ // What makes a good checkpoint block?
+ // + Is surrounded by blocks with reasonable timestamps
+ // (no blocks before with a timestamp after, none after with
+ // timestamp before)
+ // + Contains no strange transactions
+ //
+ static MapCheckpoints mapCheckpoints =
+ boost::assign::map_list_of
+ ( 11111, uint256("0x0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d"))
+ ( 33333, uint256("0x000000002dd5588a74784eaa7ab0507a18ad16a236e7b1ce69f00d7ddfb5d0a6"))
+ ( 68555, uint256("0x00000000001e1b4903550a0b96e9a9405c8a95f387162e4944e8d9fbe501cd6a"))
+ ( 70567, uint256("0x00000000006a49b14bcf27462068f1264c961f11fa2e0eddd2be0791e1d4124a"))
+ ( 74000, uint256("0x0000000000573993a3c9e41ce34471c079dcf5f52a0e824a81e7f953b8661a20"))
+ (105000, uint256("0x00000000000291ce28027faea320c8d2b054b2e0fe44a773f3eefb151d6bdc97"))
+ (118000, uint256("0x000000000000774a7f8a7a12dc906ddb9e17e75d684f15e00f8767f9e8f36553"))
+ (134444, uint256("0x00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe"))
+ (140700, uint256("0x000000000000033b512028abb90e1626d8b346fd0ed598ac0a3c371138dce2bd"))
+ (168000, uint256("0x000000000000099e61ea72015e79632f216fe6cb33d7899acb35b75c8303b763"))
+ ;
+
+ bool CheckBlock(int nHeight, const uint256& hash)
+ {
+ if (fTestNet) return true; // Testnet has no checkpoints
+
+ MapCheckpoints::const_iterator i = mapCheckpoints.find(nHeight);
+ if (i == mapCheckpoints.end()) return true;
+ return hash == i->second;
+ }
+
+ int GetTotalBlocksEstimate()
+ {
+ if (fTestNet) return 0;
+
+ return mapCheckpoints.rbegin()->first;
+ }
+
+ CBlockIndex* GetLastCheckpoint(const std::map<uint256, CBlockIndex*>& mapBlockIndex)
+ {
+ if (fTestNet) return NULL;
+
+ BOOST_REVERSE_FOREACH(const MapCheckpoints::value_type& i, mapCheckpoints)
+ {
+ const uint256& hash = i.second;
+ std::map<uint256, CBlockIndex*>::const_iterator t = mapBlockIndex.find(hash);
+ if (t != mapBlockIndex.end())
+ return t->second;
+ }
+ return NULL;
+ }
+}
--- /dev/null
+// Copyright (c) 2011 The Bitcoin developers
+// Distributed under the MIT/X11 software license, see the accompanying
+// file license.txt or http://www.opensource.org/licenses/mit-license.php.
+#ifndef BITCOIN_CHECKPOINT_H
+#define BITCOIN_CHECKPOINT_H
+
+#include <map>
+#include "util.h"
+
+class uint256;
+class CBlockIndex;
+
+//
+// Block-chain checkpoints are compiled-in sanity checks.
+// They are updated every release or three.
+//
+namespace Checkpoints
+{
+ // Returns true if block passes checkpoint checks
+ bool CheckBlock(int nHeight, const uint256& hash);
+
+ // Return conservative estimate of total number of blocks, 0 if unknown
+ int GetTotalBlocksEstimate();
+
+ // Returns last CBlockIndex* in mapBlockIndex that is a checkpoint
+ CBlockIndex* GetLastCheckpoint(const std::map<uint256, CBlockIndex*>& mapBlockIndex);
+}
+
+#endif
#include "main.h"
#include "util.h"
-bool CCrypter::SetKeyFromPassphrase(const std::string& strKeyData, const std::vector<unsigned char>& chSalt, const unsigned int nRounds, const unsigned int nDerivationMethod)
+bool CCrypter::SetKeyFromPassphrase(const SecureString& strKeyData, const std::vector<unsigned char>& chSalt, const unsigned int nRounds, const unsigned int nDerivationMethod)
{
if (nRounds < 1 || chSalt.size() != WALLET_CRYPTO_SALT_SIZE)
return false;
EVP_CIPHER_CTX ctx;
- EVP_CIPHER_CTX_init(&ctx);
- EVP_EncryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, chKey, chIV);
-
- EVP_EncryptUpdate(&ctx, &vchCiphertext[0], &nCLen, &vchPlaintext[0], nLen);
- EVP_EncryptFinal_ex(&ctx, (&vchCiphertext[0])+nCLen, &nFLen);
+ bool fOk = true;
+ EVP_CIPHER_CTX_init(&ctx);
+ if (fOk) fOk = EVP_EncryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, chKey, chIV);
+ if (fOk) fOk = EVP_EncryptUpdate(&ctx, &vchCiphertext[0], &nCLen, &vchPlaintext[0], nLen);
+ if (fOk) fOk = EVP_EncryptFinal_ex(&ctx, (&vchCiphertext[0])+nCLen, &nFLen);
EVP_CIPHER_CTX_cleanup(&ctx);
+ if (!fOk) return false;
+
vchCiphertext.resize(nCLen + nFLen);
return true;
}
EVP_CIPHER_CTX ctx;
- EVP_CIPHER_CTX_init(&ctx);
- EVP_DecryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, chKey, chIV);
-
- EVP_DecryptUpdate(&ctx, &vchPlaintext[0], &nPLen, &vchCiphertext[0], nLen);
- EVP_DecryptFinal_ex(&ctx, (&vchPlaintext[0])+nPLen, &nFLen);
+ bool fOk = true;
+ EVP_CIPHER_CTX_init(&ctx);
+ if (fOk) fOk = EVP_DecryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, chKey, chIV);
+ if (fOk) fOk = EVP_DecryptUpdate(&ctx, &vchPlaintext[0], &nPLen, &vchCiphertext[0], nLen);
+ if (fOk) fOk = EVP_DecryptFinal_ex(&ctx, (&vchPlaintext[0])+nPLen, &nFLen);
EVP_CIPHER_CTX_cleanup(&ctx);
+ if (!fOk) return false;
+
vchPlaintext.resize(nPLen + nFLen);
return true;
}
bool fKeySet;
public:
- bool SetKeyFromPassphrase(const std::string &strKeyData, const std::vector<unsigned char>& chSalt, const unsigned int nRounds, const unsigned int nDerivationMethod);
+ bool SetKeyFromPassphrase(const SecureString &strKeyData, const std::vector<unsigned char>& chSalt, const unsigned int nRounds, const unsigned int nDerivationMethod);
bool Encrypt(const CKeyingMaterial& vchPlaintext, std::vector<unsigned char> &vchCiphertext);
bool Decrypt(const std::vector<unsigned char>& vchCiphertext, CKeyingMaterial& vchPlaintext);
bool SetKey(const CKeyingMaterial& chNewKey, const std::vector<unsigned char>& chNewIV);
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2011 The Bitcoin developers
+// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
//// todo: shouldn't we catch exceptions and try to recover and continue?
CRITICAL_BLOCK(pwallet->cs_wallet)
{
+ int nMinVersion = 0;
+ if (Read((string)"minversion", nMinVersion))
+ {
+ if (nMinVersion > VERSION)
+ return DB_TOO_NEW;
+ }
+
// Get cursor
Dbc* pcursor = GetCursor();
if (!pcursor)
+ {
+ printf("Error getting wallet database cursor\n");
return DB_CORRUPT;
+ }
loop
{
if (ret == DB_NOTFOUND)
break;
else if (ret != 0)
+ {
+ printf("Error reading next record from wallet database\n");
return DB_CORRUPT;
+ }
// Unserialize
// Taking advantage of the fact that pair serialization
CPrivKey pkey;
ssValue >> pkey;
key.SetPrivKey(pkey);
+ if (key.GetPubKey() != vchPubKey)
+ {
+ printf("Error reading wallet database: CPrivKey pubkey inconsistency\n");
+ return DB_CORRUPT;
+ }
+ if (!key.IsValid())
+ {
+ printf("Error reading wallet database: invalid CPrivKey\n");
+ return DB_CORRUPT;
+ }
}
else
{
CWalletKey wkey;
ssValue >> wkey;
key.SetPrivKey(wkey.vchPrivKey);
+ if (key.GetPubKey() != vchPubKey)
+ {
+ printf("Error reading wallet database: CWalletKey pubkey inconsistency\n");
+ return DB_CORRUPT;
+ }
+ if (!key.IsValid())
+ {
+ printf("Error reading wallet database: invalid CWalletKey\n");
+ return DB_CORRUPT;
+ }
}
if (!pwallet->LoadKey(key))
+ {
+ printf("Error reading wallet database: LoadKey failed\n");
return DB_CORRUPT;
+ }
}
else if (strType == "mkey")
{
CMasterKey kMasterKey;
ssValue >> kMasterKey;
if(pwallet->mapMasterKeys.count(nID) != 0)
+ {
+ printf("Error reading wallet database: duplicate CMasterKey id %u\n", nID);
return DB_CORRUPT;
+ }
pwallet->mapMasterKeys[nID] = kMasterKey;
if (pwallet->nMasterKeyMaxID < nID)
pwallet->nMasterKeyMaxID = nID;
vector<unsigned char> vchPrivKey;
ssValue >> vchPrivKey;
if (!pwallet->LoadCryptedKey(vchPubKey, vchPrivKey))
+ {
+ printf("Error reading wallet database: LoadCryptedKey failed\n");
return DB_CORRUPT;
+ }
fIsEncrypted = true;
}
else if (strType == "defaultkey")
if (strKey == "addrProxy") ssValue >> addrProxy;
if (fHaveUPnP && strKey == "fUseUPnP") ssValue >> fUseUPnP;
}
- else if (strType == "minversion")
- {
- int nMinVersion = 0;
- ssValue >> nMinVersion;
- if (nMinVersion > VERSION)
- return DB_TOO_NEW;
- }
}
pcursor->close();
}
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2011 The Bitcoin developers
+// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
#endif
-#pragma hdrstop
-
#include "serialize.h"
#include "uint256.h"
#include "util.h"
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2011 The Bitcoin developers
+// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
#include "headers.h"
Q_IMPORT_PLUGIN(qjpcodecs)
Q_IMPORT_PLUGIN(qtwcodecs)
Q_IMPORT_PLUGIN(qkrcodecs)
+Q_IMPORT_PLUGIN(qtaccessiblewidgets)
#endif
using namespace std;
string strUsage = string() +
_("Bitcoin version") + " " + FormatFullVersion() + "\n\n" +
_("Usage:") + "\t\t\t\t\t\t\t\t\t\t\n" +
- " bitcoin [options] \t " + "\n" +
- " bitcoin [options] <command> [params]\t " + _("Send command to -server or bitcoind\n") +
- " bitcoin [options] help \t\t " + _("List commands\n") +
- " bitcoin [options] help <command> \t\t " + _("Get help for a command\n") +
+ " bitcoind [options] \t " + "\n" +
+ " bitcoind [options] <command> [params]\t " + _("Send command to -server or bitcoind\n") +
+ " bitcoind [options] help \t\t " + _("List commands\n") +
+ " bitcoind [options] help <command> \t\t " + _("Get help for a command\n") +
_("Options:\n") +
" -conf=<file> \t\t " + _("Specify configuration file (default: bitcoin.conf)\n") +
" -pid=<file> \t\t " + _("Specify pid file (default: bitcoind.pid)\n") +
" -timeout=<n> \t " + _("Specify connection timeout (in milliseconds)\n") +
" -proxy=<ip:port> \t " + _("Connect through socks4 proxy\n") +
" -dns \t " + _("Allow DNS lookups for addnode and connect\n") +
+ " -port=<port> \t\t " + _("Listen for connections on <port> (default: 8333 or testnet: 18333)\n") +
+ " -maxconnections=<n>\t " + _("Maintain at most <n> connections to peers (default: 125)\n") +
" -addnode=<ip> \t " + _("Add a node to connect to\n") +
" -connect=<ip> \t\t " + _("Connect only to the specified node\n") +
+ " -noirc \t " + _("Don't find peers using internet relay chat\n") +
" -nolisten \t " + _("Don't accept connections from outside\n") +
+ " -nodnsseed \t " + _("Don't bootstrap list of peers using DNS\n") +
" -banscore=<n> \t " + _("Threshold for disconnecting misbehaving peers (default: 100)\n") +
" -bantime=<n> \t " + _("Number of seconds to keep misbehaving peers from reconnecting (default: 86400)\n") +
+ " -maxreceivebuffer=<n>\t " + _("Maximum per-connection receive buffer, <n>*1000 bytes (default: 10000)\n") +
+ " -maxsendbuffer=<n>\t " + _("Maximum per-connection send buffer, <n>*1000 bytes (default: 10000)\n") +
#ifdef USE_UPNP
#if USE_UPNP
" -noupnp \t " + _("Don't attempt to use UPnP to map the listening port\n") +
" -upnp \t " + _("Attempt to use UPnP to map the listening port\n") +
#endif
#endif
- " -paytxfee=<amt> \t " + _("Fee per KB to add to transactions you send\n") +
-#ifdef GUI
+ " -paytxfee=<amt> \t " + _("Fee per kB to add to transactions you send\n") +
+#ifdef QT_GUI
" -server \t\t " + _("Accept command line and JSON-RPC commands\n") +
#endif
-#ifndef WIN32
+#if !defined(WIN32) && !defined(QT_GUI)
" -daemon \t\t " + _("Run in the background as a daemon and accept commands\n") +
#endif
" -testnet \t\t " + _("Use the test network\n") +
+ " -debug \t\t " + _("Output extra debugging information\n") +
+ " -logtimestamps \t " + _("Prepend debug output with timestamp\n") +
+ " -printtoconsole \t " + _("Send trace/debug info to console instead of debug.log file\n") +
+#ifdef WIN32
+ " -printtodebugger \t " + _("Send trace/debug info to debugger\n") +
+#endif
" -rpcuser=<user> \t " + _("Username for JSON-RPC connections\n") +
" -rpcpassword=<pw>\t " + _("Password for JSON-RPC connections\n") +
" -rpcport=<port> \t\t " + _("Listen for JSON-RPC connections on <port> (default: 8332)\n") +
// Remove tabs
strUsage.erase(std::remove(strUsage.begin(), strUsage.end(), '\t'), strUsage.end());
+#if defined(QT_GUI) && defined(WIN32)
+ // On windows, show a message box, as there is no stderr
+ wxMessageBox(strUsage, "Usage");
+#else
fprintf(stderr, "%s", strUsage.c_str());
+#endif
return false;
}
+ fTestNet = GetBoolArg("-testnet");
fDebug = GetBoolArg("-debug");
- fAllowDNS = GetBoolArg("-dns");
-#ifndef WIN32
+#if !defined(WIN32) && !defined(QT_GUI)
fDaemon = GetBoolArg("-daemon");
#else
fDaemon = false;
#endif
fPrintToConsole = GetBoolArg("-printtoconsole");
fPrintToDebugger = GetBoolArg("-printtodebugger");
-
- fTestNet = GetBoolArg("-testnet");
- bool fTOR = (fUseProxy && addrProxy.port == htons(9050));
- fNoListen = GetBoolArg("-nolisten") || fTOR;
fLogTimestamps = GetBoolArg("-logtimestamps");
#ifndef QT_GUI
}
#endif
-#ifndef WIN32
+#if !defined(WIN32) && !defined(QT_GUI)
if (fDaemon)
{
// Daemonize
return false;
}
- // Bind to the port early so we can tell if another instance is already running.
string strErrors;
- if (!fNoListen)
- {
- if (!BindListenPort(strErrors))
- {
- wxMessageBox(strErrors, "Bitcoin");
- return false;
- }
- }
//
// Load data files
else if (nLoadWalletRet == DB_NEED_REWRITE)
{
strErrors += _("Wallet needed to be rewritten: restart Bitcoin to complete \n");
+ printf("%s", strErrors.c_str());
wxMessageBox(strErrors, "Bitcoin", wxOK | wxICON_ERROR);
return false;
}
else
strErrors += _("Error loading wallet.dat \n");
}
+ printf("%s", strErrors.c_str());
printf(" wallet %15"PRI64d"ms\n", GetTimeMillis() - nStart);
RegisterWallet(pwalletMain);
// Add wallet transactions that aren't already in a block to mapTransactions
pwalletMain->ReacceptWalletTransactions();
+ // Note: Bitcoin-QT stores several settings in the wallet, so we want
+ // to load the wallet BEFORE parsing command-line arguments, so
+ // the command-line/bitcoin.conf settings override GUI setting.
+
//
// Parameters
//
}
}
+ bool fTor = (fUseProxy && addrProxy.port == htons(9050));
+ if (fTor)
+ {
+ // Use SoftSetArg here so user can override any of these if they wish.
+ // Note: the GetBoolArg() calls for all of these must happen later.
+ SoftSetArg("-nolisten", true);
+ SoftSetArg("-noirc", true);
+ SoftSetArg("-nodnsseed", true);
+ SoftSetArg("-noupnp", true);
+ SoftSetArg("-upnp", false);
+ SoftSetArg("-dns", false);
+ }
+
+ fAllowDNS = GetBoolArg("-dns");
+ fNoListen = GetBoolArg("-nolisten");
+
+ // Command-line args override in-wallet settings:
+ if (mapArgs.count("-upnp"))
+ fUseUPnP = GetBoolArg("-upnp");
+ else if (mapArgs.count("-noupnp"))
+ fUseUPnP = !GetBoolArg("-noupnp");
+
+ if (!fNoListen)
+ {
+ if (!BindListenPort(strErrors))
+ {
+ wxMessageBox(strErrors, "Bitcoin");
+ return false;
+ }
+ }
+
if (mapArgs.count("-addnode"))
{
BOOST_FOREACH(string strAddr, mapMultiArgs["-addnode"])
}
}
- if (GetBoolArg("-nodnsseed"))
- printf("DNS seeding disabled\n");
- else
- DNSAddressSeed();
-
if (mapArgs.count("-paytxfee"))
{
if (!ParseMoney(mapArgs["-paytxfee"], nTransactionFee))
wxMessageBox(_("Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction."), "Bitcoin", wxOK | wxICON_EXCLAMATION);
}
- if (fHaveUPnP)
- {
-#if USE_UPNP
- if (GetBoolArg("-noupnp"))
- fUseUPnP = false;
-#else
- if (GetBoolArg("-upnp"))
- fUseUPnP = true;
-#endif
- }
-
//
// Start the node
//
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2011 The Bitcoin developers
+// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
if (nBytes == 0)
{
// socket closed
- printf("IRC socket closed\n");
+ printf("socket closed\n");
return false;
}
else
{
// socket error
int nErr = WSAGetLastError();
- printf("IRC recv failed: %d\n", nErr);
+ printf("recv failed: %d\n", nErr);
return false;
}
}
int nErrorWait = 10;
int nRetryWait = 10;
bool fNameInUse = false;
- bool fTOR = (fUseProxy && addrProxy.port == htons(9050));
while (!fShutdown)
{
- //CAddress addrConnect("216.155.130.130:6667"); // chat.freenode.net
CAddress addrConnect("92.243.23.21", 6667); // irc.lfnet.org
- if (!fTOR)
- {
- //struct hostent* phostent = gethostbyname("chat.freenode.net");
- CAddress addrIRC("irc.lfnet.org", 6667, true);
- if (addrIRC.IsValid())
- addrConnect = addrIRC;
- }
+
+ CAddress addrIRC("irc.lfnet.org", 6667, true);
+ if (addrIRC.IsValid())
+ addrConnect = addrIRC;
SOCKET hSocket;
if (!ConnectSocket(addrConnect, hSocket))
closesocket(hSocket);
hSocket = INVALID_SOCKET;
- // IRC usually blocks TOR, so only try once
- if (fTOR)
- return;
-
if (GetTime() - nStart > 20 * 60)
{
nErrorWait /= 3;
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2011 The Bitcoin developers
+// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_KEY_H
EC_KEY* pkey;
bool fSet;
+ void SetCompressedPubKey()
+ {
+ EC_KEY_set_conv_form(pkey, POINT_CONVERSION_COMPRESSED);
+ }
+
public:
CKey()
{
if (vchSecret.size() != 32)
throw key_error("CKey::SetSecret() : secret must be 32 bytes");
BIGNUM *bn = BN_bin2bn(&vchSecret[0],32,BN_new());
- if (bn == NULL)
+ if (bn == NULL)
throw key_error("CKey::SetSecret() : BN_bin2bn failed");
if (!EC_KEY_regenerate_key(pkey,bn))
+ {
+ BN_clear_free(bn);
throw key_error("CKey::SetSecret() : EC_KEY_regenerate_key failed");
+ }
BN_clear_free(bn);
fSet = true;
return true;
bool Sign(uint256 hash, std::vector<unsigned char>& vchSig)
{
- vchSig.clear();
- unsigned char pchSig[10000];
- unsigned int nSize = 0;
- if (!ECDSA_sign(0, (unsigned char*)&hash, sizeof(hash), pchSig, &nSize, pkey))
+ unsigned int nSize = ECDSA_size(pkey);
+ vchSig.resize(nSize); // Make sure it is big enough
+ if (!ECDSA_sign(0, (unsigned char*)&hash, sizeof(hash), &vchSig[0], &nSize, pkey))
+ {
+ vchSig.clear();
return false;
- vchSig.resize(nSize);
- memcpy(&vchSig[0], pchSig, nSize);
+ }
+ vchSig.resize(nSize); // Shrink to fit actual size
return true;
}
{
if (vchSig.size() != 65)
return false;
- if (vchSig[0]<27 || vchSig[0]>=31)
+ int nV = vchSig[0];
+ if (nV<27 || nV>=35)
return false;
ECDSA_SIG *sig = ECDSA_SIG_new();
BN_bin2bn(&vchSig[1],32,sig->r);
EC_KEY_free(pkey);
pkey = EC_KEY_new_by_curve_name(NID_secp256k1);
- if (ECDSA_SIG_recover_key_GFp(pkey, sig, (unsigned char*)&hash, sizeof(hash), vchSig[0] - 27, 0) == 1)
+ if (nV >= 31)
+ {
+ SetCompressedPubKey();
+ nV -= 4;
+ }
+ if (ECDSA_SIG_recover_key_GFp(pkey, sig, (unsigned char*)&hash, sizeof(hash), nV - 27, 0) == 1)
{
fSet = true;
ECDSA_SIG_free(sig);
{
return CBitcoinAddress(GetPubKey());
}
+
+ bool IsValid()
+ {
+ if (!fSet)
+ return false;
+
+ CSecret secret = GetSecret();
+ CKey key2;
+ key2.SetSecret(secret);
+ return GetPubKey() == key2.GetPubKey();
+ }
};
#endif
CSecret vchSecret;
if(!DecryptSecret(vMasterKeyIn, vchCryptedSecret, Hash(vchPubKey.begin(), vchPubKey.end()), vchSecret))
return false;
+ if (vchSecret.size() != 32)
+ return false;
CKey key;
key.SetSecret(vchSecret);
if (key.GetPubKey() == vchPubKey)
CSecret vchSecret;
if (!DecryptSecret(vMasterKey, vchCryptedSecret, Hash(vchPubKey.begin(), vchPubKey.end()), vchSecret))
return false;
+ if (vchSecret.size() != 32)
+ return false;
keyOut.SetSecret(vchSecret);
return true;
}
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2011 The Bitcoin developers
+// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
#include "headers.h"
+#include "checkpoints.h"
#include "db.h"
#include "net.h"
#include "init.h"
map<uint256, CBlockIndex*> mapBlockIndex;
uint256 hashGenesisBlock("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f");
static CBigNum bnProofOfWorkLimit(~uint256(0) >> 32);
-const int nTotalBlocksEstimate = 140700; // Conservative estimate of total nr of blocks on main chain
-const int nInitialBlockThreshold = 120; // Regard blocks up until N-threshold as "initial download"
CBlockIndex* pindexGenesisBlock = NULL;
int nBestHeight = -1;
CBigNum bnBestChainWork = 0;
// mapOrphanTransactions
//
-void static AddOrphanTx(const CDataStream& vMsg)
+void AddOrphanTx(const CDataStream& vMsg)
{
CTransaction tx;
CDataStream(vMsg) >> tx;
uint256 hash = tx.GetHash();
if (mapOrphanTransactions.count(hash))
return;
+
CDataStream* pvMsg = mapOrphanTransactions[hash] = new CDataStream(vMsg);
BOOST_FOREACH(const CTxIn& txin, tx.vin)
mapOrphanTransactionsByPrev.insert(make_pair(txin.prevout.hash, pvMsg));
mapOrphanTransactions.erase(hash);
}
+int LimitOrphanTxSize(int nMaxOrphans)
+{
+ int nEvicted = 0;
+ while (mapOrphanTransactions.size() > nMaxOrphans)
+ {
+ // Evict a random orphan:
+ std::vector<unsigned char> randbytes(32);
+ RAND_bytes(&randbytes[0], 32);
+ uint256 randomhash(randbytes);
+ map<uint256, CDataStream*>::iterator it = mapOrphanTransactions.lower_bound(randomhash);
+ if (it == mapOrphanTransactions.end())
+ it = mapOrphanTransactions.begin();
+ EraseOrphanTx(it->first);
+ ++nEvicted;
+ }
+ return nEvicted;
+}
if ((int64)nLockTime > INT_MAX)
return error("AcceptToMemoryPool() : not accepting nLockTime beyond 2038 yet");
- // Safety limits
- unsigned int nSize = ::GetSerializeSize(*this, SER_NETWORK);
- // Checking ECDSA signatures is a CPU bottleneck, so to avoid denial-of-service
- // attacks disallow transactions with more than one SigOp per 34 bytes.
- // 34 bytes because a TxOut is:
- // 20-byte address + 8 byte bitcoin amount + 5 bytes of ops + 1 byte script length
- if (GetSigOpCount() > nSize / 34 || nSize < 100)
- return error("AcceptToMemoryPool() : transaction with out-of-bounds SigOpCount");
-
// Rather not work on nonstandard transactions (unless -testnet)
if (!fTestNet && !IsStandard())
return error("AcceptToMemoryPool() : nonstandard transaction type");
if (fCheckInputs)
{
- // Check against previous transactions
+ MapPrevTx mapInputs;
map<uint256, CTxIndex> mapUnused;
- int64 nFees = 0;
- if (!ConnectInputs(txdb, mapUnused, CDiskTxPos(1,1,1), pindexBest, nFees, false, false))
+ bool fInvalid = false;
+ if (!FetchInputs(txdb, mapUnused, false, false, mapInputs, fInvalid))
{
+ if (fInvalid)
+ return error("AcceptToMemoryPool() : FetchInputs found invalid tx %s", hash.ToString().substr(0,10).c_str());
if (pfMissingInputs)
*pfMissingInputs = true;
- return error("AcceptToMemoryPool() : ConnectInputs failed %s", hash.ToString().substr(0,10).c_str());
+ return error("AcceptToMemoryPool() : FetchInputs failed %s", hash.ToString().substr(0,10).c_str());
}
+ // Safety limits
+ unsigned int nSize = ::GetSerializeSize(*this, SER_NETWORK);
+ // Checking ECDSA signatures is a CPU bottleneck, so to avoid denial-of-service
+ // attacks disallow transactions with more than one SigOp per 34 bytes.
+ // 34 bytes because a TxOut is:
+ // 20-byte address + 8 byte bitcoin amount + 5 bytes of ops + 1 byte script length
+ if (GetSigOpCount() > nSize / 34 || nSize < 100)
+ return error("AcceptToMemoryPool() : transaction with out-of-bounds SigOpCount");
+
+ int64 nFees = GetValueIn(mapInputs)-GetValueOut();
+
// Don't accept it if it can't get into a block
if (nFees < GetMinFee(1000, true, true))
return error("AcceptToMemoryPool() : not enough fees");
dFreeCount += nSize;
}
}
+
+ // Check against previous transactions
+ // This is done last to help prevent CPU exhaustion denial-of-service attacks.
+ if (!ConnectInputs(mapInputs, mapUnused, CDiskTxPos(1,1,1), pindexBest, false, false))
+ {
+ return error("AcceptToMemoryPool() : ConnectInputs failed %s", hash.ToString().substr(0,10).c_str());
+ }
}
// Store transaction in memory
return nSubsidy + nFees;
}
-unsigned int static GetNextWorkRequired(const CBlockIndex* pindexLast)
+static const int64 nTargetTimespan = 14 * 24 * 60 * 60; // two weeks
+static const int64 nTargetSpacing = 10 * 60;
+static const int64 nInterval = nTargetTimespan / nTargetSpacing;
+
+//
+// minimum amount of work that could possibly be required nTime after
+// minimum work required was nBase
+//
+unsigned int ComputeMinWork(unsigned int nBase, int64 nTime)
{
- const int64 nTargetTimespan = 14 * 24 * 60 * 60; // two weeks
- const int64 nTargetSpacing = 10 * 60;
- const int64 nInterval = nTargetTimespan / nTargetSpacing;
+ // Testnet has min-difficulty blocks
+ // after nTargetSpacing*2 time between blocks:
+ if (fTestNet && nTime > nTargetSpacing*2)
+ return bnProofOfWorkLimit.GetCompact();
+
+ CBigNum bnResult;
+ bnResult.SetCompact(nBase);
+ while (nTime > 0 && bnResult < bnProofOfWorkLimit)
+ {
+ // Maximum 400% adjustment...
+ bnResult *= 4;
+ // ... in best-case exactly 4-times-normal target time
+ nTime -= nTargetTimespan*4;
+ }
+ if (bnResult > bnProofOfWorkLimit)
+ bnResult = bnProofOfWorkLimit;
+ return bnResult.GetCompact();
+}
+
+unsigned int static GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlock *pblock)
+{
+ unsigned int nProofOfWorkLimit = bnProofOfWorkLimit.GetCompact();
// Genesis block
if (pindexLast == NULL)
- return bnProofOfWorkLimit.GetCompact();
+ return nProofOfWorkLimit;
// Only change once per interval
if ((pindexLast->nHeight+1) % nInterval != 0)
+ {
+ // Special rules for testnet after 15 Feb 2012:
+ if (fTestNet && pblock->nTime > 1329264000)
+ {
+ // If the new block's timestamp is more than 2* 10 minutes
+ // then allow mining of a min-difficulty block.
+ if (pblock->nTime - pindexLast->nTime > nTargetSpacing*2)
+ return nProofOfWorkLimit;
+ else
+ {
+ // Return the last non-special-min-difficulty-rules-block
+ const CBlockIndex* pindex = pindexLast;
+ while (pindex->pprev && pindex->nHeight % nInterval != 0 && pindex->nBits == nProofOfWorkLimit)
+ pindex = pindex->pprev;
+ return pindex->nBits;
+ }
+ }
+
return pindexLast->nBits;
+ }
// Go back by what we want to be 14 days worth of blocks
const CBlockIndex* pindexFirst = pindexLast;
return true;
}
-// Return conservative estimate of total number of blocks, 0 if unknown
-int GetTotalBlocksEstimate()
-{
- if(fTestNet)
- {
- return 0;
- }
- else
- {
- return nTotalBlocksEstimate;
- }
-}
-
// Return maximum amount of blocks that other nodes claim to have
int GetNumBlocksOfPeers()
{
- return std::max(cPeerBlockCounts.median(), GetTotalBlocksEstimate());
+ return std::max(cPeerBlockCounts.median(), Checkpoints::GetTotalBlocksEstimate());
}
bool IsInitialBlockDownload()
{
- if (pindexBest == NULL || nBestHeight < (GetTotalBlocksEstimate()-nInitialBlockThreshold))
+ if (pindexBest == NULL || nBestHeight < Checkpoints::GetTotalBlocksEstimate())
return true;
static int64 nLastUpdate;
static CBlockIndex* pindexLastBest;
printf("InvalidChainFound: WARNING: Displayed transactions may not be correct! You may need to upgrade, or other nodes may need to upgrade.\n");
}
+void CBlock::UpdateTime(const CBlockIndex* pindexPrev)
+{
+ nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
+
+ // Updating time can change work required on testnet:
+ if (fTestNet)
+ nBits = GetNextWorkRequired(pindexPrev, this);
+}
+
}
// Remove transaction from index
- if (!txdb.EraseTxIndex(*this))
- return error("DisconnectInputs() : EraseTxPos failed");
+ // This can fail if a duplicate of this transaction was in a chain that got
+ // reorganized away. This is only possible if this transaction was completely
+ // spent, so erasing it would be a no-op anway.
+ txdb.EraseTxIndex(*this);
return true;
}
-bool CTransaction::ConnectInputs(CTxDB& txdb, map<uint256, CTxIndex>& mapTestPool, CDiskTxPos posThisTx,
- CBlockIndex* pindexBlock, int64& nFees, bool fBlock, bool fMiner, int64 nMinFee)
+bool CTransaction::FetchInputs(CTxDB& txdb, const map<uint256, CTxIndex>& mapTestPool,
+ bool fBlock, bool fMiner, MapPrevTx& inputsRet, bool& fInvalid)
+{
+ // FetchInputs can return false either because we just haven't seen some inputs
+ // (in which case the transaction should be stored as an orphan)
+ // or because the transaction is malformed (in which case the transaction should
+ // be dropped). If tx is definitely invalid, fInvalid will be set to true.
+ fInvalid = false;
+
+ if (IsCoinBase())
+ return true; // Coinbase transactions have no inputs to fetch.
+
+ for (int i = 0; i < vin.size(); i++)
+ {
+ COutPoint prevout = vin[i].prevout;
+ if (inputsRet.count(prevout.hash))
+ continue; // Got it already
+
+ // Read txindex
+ CTxIndex& txindex = inputsRet[prevout.hash].first;
+ bool fFound = true;
+ if ((fBlock || fMiner) && mapTestPool.count(prevout.hash))
+ {
+ // Get txindex from current proposed changes
+ txindex = mapTestPool.find(prevout.hash)->second;
+ }
+ else
+ {
+ // Read txindex from txdb
+ fFound = txdb.ReadTxIndex(prevout.hash, txindex);
+ }
+ if (!fFound && (fBlock || fMiner))
+ return fMiner ? false : error("FetchInputs() : %s prev tx %s index entry not found", GetHash().ToString().substr(0,10).c_str(), prevout.hash.ToString().substr(0,10).c_str());
+
+ // Read txPrev
+ CTransaction& txPrev = inputsRet[prevout.hash].second;
+ if (!fFound || txindex.pos == CDiskTxPos(1,1,1))
+ {
+ // Get prev tx from single transactions in memory
+ CRITICAL_BLOCK(cs_mapTransactions)
+ {
+ if (!mapTransactions.count(prevout.hash))
+ return error("FetchInputs() : %s mapTransactions prev not found %s", GetHash().ToString().substr(0,10).c_str(), prevout.hash.ToString().substr(0,10).c_str());
+ txPrev = mapTransactions[prevout.hash];
+ }
+ if (!fFound)
+ txindex.vSpent.resize(txPrev.vout.size());
+ }
+ else
+ {
+ // Get prev tx from disk
+ if (!txPrev.ReadFromDisk(txindex.pos))
+ return error("FetchInputs() : %s ReadFromDisk prev tx %s failed", GetHash().ToString().substr(0,10).c_str(), prevout.hash.ToString().substr(0,10).c_str());
+ }
+ }
+
+ // Make sure all prevout.n's are valid:
+ for (int i = 0; i < vin.size(); i++)
+ {
+ const COutPoint prevout = vin[i].prevout;
+ assert(inputsRet.count(prevout.hash) != 0);
+ const CTxIndex& txindex = inputsRet[prevout.hash].first;
+ const CTransaction& txPrev = inputsRet[prevout.hash].second;
+ if (prevout.n >= txPrev.vout.size() || prevout.n >= txindex.vSpent.size())
+ {
+ // Revisit this if/when transaction replacement is implemented and allows
+ // adding inputs:
+ fInvalid = true;
+ return DoS(100, error("FetchInputs() : %s prevout.n out of range %d %d %d prev tx %s\n%s", GetHash().ToString().substr(0,10).c_str(), prevout.n, txPrev.vout.size(), txindex.vSpent.size(), prevout.hash.ToString().substr(0,10).c_str(), txPrev.ToString().c_str()));
+ }
+ }
+
+ return true;
+}
+
+const CTxOut& CTransaction::GetOutputFor(const CTxIn& input, const MapPrevTx& inputs) const
+{
+ MapPrevTx::const_iterator mi = inputs.find(input.prevout.hash);
+ if (mi == inputs.end())
+ throw std::runtime_error("CTransaction::GetOutputFor() : prevout.hash not found");
+
+ const CTransaction& txPrev = (mi->second).second;
+ if (input.prevout.n >= txPrev.vout.size())
+ throw std::runtime_error("CTransaction::GetOutputFor() : prevout.n out of range");
+
+ return txPrev.vout[input.prevout.n];
+}
+
+int64 CTransaction::GetValueIn(const MapPrevTx& inputs) const
+{
+ if (IsCoinBase())
+ return 0;
+
+ int64 nResult = 0;
+ for (int i = 0; i < vin.size(); i++)
+ {
+ nResult += GetOutputFor(vin[i], inputs).nValue;
+ }
+ return nResult;
+
+}
+
+int CTransaction::GetP2SHSigOpCount(const MapPrevTx& inputs) const
+{
+ if (IsCoinBase())
+ return 0;
+
+ int nSigOps = 0;
+ for (int i = 0; i < vin.size(); i++)
+ {
+ const CTxOut& prevout = GetOutputFor(vin[i], inputs);
+ if (prevout.scriptPubKey.IsPayToScriptHash())
+ nSigOps += prevout.scriptPubKey.GetSigOpCount(vin[i].scriptSig);
+ }
+ return nSigOps;
+}
+
+bool CTransaction::ConnectInputs(MapPrevTx inputs,
+ map<uint256, CTxIndex>& mapTestPool, const CDiskTxPos& posThisTx,
+ const CBlockIndex* pindexBlock, bool fBlock, bool fMiner, bool fStrictPayToScriptHash)
{
// Take over previous transactions' spent pointers
// fBlock is true when this is called from AcceptBlock when a new best-block is added to the blockchain
if (!IsCoinBase())
{
int64 nValueIn = 0;
+ int64 nFees = 0;
for (int i = 0; i < vin.size(); i++)
{
COutPoint prevout = vin[i].prevout;
-
- // Read txindex
- CTxIndex txindex;
- bool fFound = true;
- if ((fBlock || fMiner) && mapTestPool.count(prevout.hash))
- {
- // Get txindex from current proposed changes
- txindex = mapTestPool[prevout.hash];
- }
- else
- {
- // Read txindex from txdb
- fFound = txdb.ReadTxIndex(prevout.hash, txindex);
- }
- if (!fFound && (fBlock || fMiner))
- return fMiner ? false : error("ConnectInputs() : %s prev tx %s index entry not found", GetHash().ToString().substr(0,10).c_str(), prevout.hash.ToString().substr(0,10).c_str());
-
- // Read txPrev
- CTransaction txPrev;
- if (!fFound || txindex.pos == CDiskTxPos(1,1,1))
- {
- // Get prev tx from single transactions in memory
- CRITICAL_BLOCK(cs_mapTransactions)
- {
- if (!mapTransactions.count(prevout.hash))
- return error("ConnectInputs() : %s mapTransactions prev not found %s", GetHash().ToString().substr(0,10).c_str(), prevout.hash.ToString().substr(0,10).c_str());
- txPrev = mapTransactions[prevout.hash];
- }
- if (!fFound)
- txindex.vSpent.resize(txPrev.vout.size());
- }
- else
- {
- // Get prev tx from disk
- if (!txPrev.ReadFromDisk(txindex.pos))
- return error("ConnectInputs() : %s ReadFromDisk prev tx %s failed", GetHash().ToString().substr(0,10).c_str(), prevout.hash.ToString().substr(0,10).c_str());
- }
+ assert(inputs.count(prevout.hash) > 0);
+ CTxIndex& txindex = inputs[prevout.hash].first;
+ CTransaction& txPrev = inputs[prevout.hash].second;
if (prevout.n >= txPrev.vout.size() || prevout.n >= txindex.vSpent.size())
return DoS(100, error("ConnectInputs() : %s prevout.n out of range %d %d %d prev tx %s\n%s", GetHash().ToString().substr(0,10).c_str(), prevout.n, txPrev.vout.size(), txindex.vSpent.size(), prevout.hash.ToString().substr(0,10).c_str(), txPrev.ToString().c_str()));
// If prev is coinbase, check that it's matured
if (txPrev.IsCoinBase())
- for (CBlockIndex* pindex = pindexBlock; pindex && pindexBlock->nHeight - pindex->nHeight < COINBASE_MATURITY; pindex = pindex->pprev)
+ for (const CBlockIndex* pindex = pindexBlock; pindex && pindexBlock->nHeight - pindex->nHeight < COINBASE_MATURITY; pindex = pindex->pprev)
if (pindex->nBlockPos == txindex.pos.nBlockPos && pindex->nFile == txindex.pos.nFile)
return error("ConnectInputs() : tried to spend coinbase at depth %d", pindexBlock->nHeight - pindex->nHeight);
- // Skip ECDSA signature verification when connecting blocks (fBlock=true) during initial download
- // (before the last blockchain checkpoint). This is safe because block merkle hashes are
- // still computed and checked, and any change will be caught at the next checkpoint.
- if (!(fBlock && IsInitialBlockDownload()))
- // Verify signature
- if (!VerifySignature(txPrev, *this, i))
- return DoS(100,error("ConnectInputs() : %s VerifySignature failed", GetHash().ToString().substr(0,10).c_str()));
-
// Check for conflicts (double-spend)
// 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 (!MoneyRange(txPrev.vout[prevout.n].nValue) || !MoneyRange(nValueIn))
return DoS(100, error("ConnectInputs() : txin values out of range"));
+ // Skip ECDSA signature verification when connecting blocks (fBlock=true)
+ // before the last blockchain checkpoint. This is safe because block merkle hashes are
+ // still computed and checked, and any change will be caught at the next checkpoint.
+ if (!(fBlock && (nBestHeight < Checkpoints::GetTotalBlocksEstimate())))
+ {
+ // Verify signature
+ if (!VerifySignature(txPrev, *this, i, fStrictPayToScriptHash, 0))
+ {
+ // only during transition phase for P2SH: do not invoke anti-DoS code for
+ // potentially old clients relaying bad P2SH transactions
+ if (fStrictPayToScriptHash && VerifySignature(txPrev, *this, i, false, 0))
+ return error("ConnectInputs() : %s P2SH VerifySignature failed", GetHash().ToString().substr(0,10).c_str());
+
+ return DoS(100,error("ConnectInputs() : %s VerifySignature failed", GetHash().ToString().substr(0,10).c_str()));
+ }
+ }
+
// Mark outpoints as spent
txindex.vSpent[prevout.n] = posThisTx;
int64 nTxFee = nValueIn - GetValueOut();
if (nTxFee < 0)
return DoS(100, error("ConnectInputs() : %s nTxFee < 0", GetHash().ToString().substr(0,10).c_str()));
- if (nTxFee < nMinFee)
- return false;
nFees += nTxFee;
if (!MoneyRange(nFees))
return DoS(100, error("ConnectInputs() : nFees out of range"));
}
- if (fBlock)
- {
- // Add transaction to changes
- mapTestPool[GetHash()] = CTxIndex(posThisTx, vout.size());
- }
- else if (fMiner)
- {
- // Add transaction to test pool
- mapTestPool[GetHash()] = CTxIndex(CDiskTxPos(1,1,1), vout.size());
- }
-
return true;
}
return false;
// Verify signature
- if (!VerifySignature(txPrev, *this, i))
+ if (!VerifySignature(txPrev, *this, i, true, 0))
return error("ConnectInputs() : VerifySignature failed");
///// this is redundant with the mapNextTx stuff, not sure which I want to get rid of
if (!CheckBlock())
return false;
+ // Do not allow blocks that contain transactions which 'overwrite' older transactions,
+ // unless those are already completely spent.
+ // If such overwrites are allowed, coinbases and transactions depending upon those
+ // can be duplicated to remove the ability to spend the first instance -- even after
+ // being sent to another address.
+ // See BIP30 and http://r6.ca/blog/20120206T005236Z.html for more information.
+ // This logic is not necessary for memory pool transactions, as AcceptToMemoryPool
+ // already refuses previously-known transaction id's entirely.
+ // This rule applies to all blocks whose timestamp is after March 15, 2012, 0:00 UTC.
+ // On testnet it is enabled as of februari 20, 2012, 0:00 UTC.
+ if (pindex->nTime > 1331769600 || (fTestNet && pindex->nTime > 1329696000))
+ BOOST_FOREACH(CTransaction& tx, vtx)
+ {
+ CTxIndex txindexOld;
+ if (txdb.ReadTxIndex(tx.GetHash(), txindexOld))
+ BOOST_FOREACH(CDiskTxPos &pos, txindexOld.vSpent)
+ if (pos.IsNull())
+ return false;
+ }
+
+ // P2SH didn't become active until Apr 1 2012 (Feb 15 on testnet)
+ int64 nEvalSwitchTime = fTestNet ? 1329264000 : 1333238400;
+ bool fStrictPayToScriptHash = (pindex->nTime >= nEvalSwitchTime);
+
//// issue here: it doesn't know the version
unsigned int nTxPos = pindex->nBlockPos + ::GetSerializeSize(CBlock(), SER_DISK) - 1 + GetSizeOfCompactSize(vtx.size());
map<uint256, CTxIndex> mapQueuedChanges;
int64 nFees = 0;
+ int nSigOps = 0;
BOOST_FOREACH(CTransaction& tx, vtx)
{
+ nSigOps += tx.GetSigOpCount();
+ if (nSigOps > MAX_BLOCK_SIGOPS)
+ return DoS(100, error("ConnectBlock() : too many sigops"));
+
CDiskTxPos posThisTx(pindex->nFile, pindex->nBlockPos, nTxPos);
nTxPos += ::GetSerializeSize(tx, SER_DISK);
- if (!tx.ConnectInputs(txdb, mapQueuedChanges, posThisTx, pindex, nFees, true, false))
- return false;
+ bool fInvalid;
+ MapPrevTx mapInputs;
+ if (!tx.IsCoinBase())
+ {
+ if (!tx.FetchInputs(txdb, mapQueuedChanges, true, false, mapInputs, fInvalid))
+ return false;
+
+ if (fStrictPayToScriptHash)
+ {
+ // Add in sigops done by pay-to-script-hash inputs;
+ // this is to prevent a "rogue miner" from creating
+ // an incredibly-expensive-to-validate block.
+ nSigOps += tx.GetP2SHSigOpCount(mapInputs);
+ if (nSigOps > MAX_BLOCK_SIGOPS)
+ return DoS(100, error("ConnectBlock() : too many sigops"));
+ }
+
+ nFees += tx.GetValueIn(mapInputs)-tx.GetValueOut();
+
+ if (!tx.ConnectInputs(mapInputs, mapQueuedChanges, posThisTx, pindex, true, false, fStrictPayToScriptHash))
+ return false;
+ }
+
+ mapQueuedChanges[tx.GetHash()] = CTxIndex(posThisTx, tx.vout.size());
}
+
// Write queued txindex changes
for (map<uint256, CTxIndex>::iterator mi = mapQueuedChanges.begin(); mi != mapQueuedChanges.end(); ++mi)
{
vConnect.push_back(pindex);
reverse(vConnect.begin(), vConnect.end());
+ printf("REORGANIZE: Disconnect %i blocks; %s..%s\n", vDisconnect.size(), pfork->GetBlockHash().ToString().substr(0,20).c_str(), pindexBest->GetBlockHash().ToString().substr(0,20).c_str());
+ printf("REORGANIZE: Connect %i blocks; %s..%s\n", vConnect.size(), pfork->GetBlockHash().ToString().substr(0,20).c_str(), pindexNew->GetBlockHash().ToString().substr(0,20).c_str());
+
// Disconnect shorter branch
vector<CTransaction> vResurrect;
BOOST_FOREACH(CBlockIndex* pindex, vDisconnect)
if (!block.ReadFromDisk(pindex))
return error("Reorganize() : ReadFromDisk for disconnect failed");
if (!block.DisconnectBlock(txdb, pindex))
- return error("Reorganize() : DisconnectBlock failed");
+ return error("Reorganize() : DisconnectBlock %s failed", pindex->GetBlockHash().ToString().substr(0,20).c_str());
// Queue memory transactions to resurrect
BOOST_FOREACH(const CTransaction& tx, block.vtx)
{
// Invalid block
txdb.TxnAbort();
- return error("Reorganize() : ConnectBlock failed");
+ return error("Reorganize() : ConnectBlock %s failed", pindex->GetBlockHash().ToString().substr(0,20).c_str());
}
// Queue memory transactions to delete
BOOST_FOREACH(CTransaction& tx, vDelete)
tx.RemoveFromMemoryPool();
+ printf("REORGANIZE: done\n");
+
return true;
}
int nHeight = pindexPrev->nHeight+1;
// Check proof of work
- if (nBits != GetNextWorkRequired(pindexPrev))
+ if (nBits != GetNextWorkRequired(pindexPrev, this))
return DoS(100, error("AcceptBlock() : incorrect proof of work"));
// Check timestamp against prev
return DoS(10, error("AcceptBlock() : contains a non-final transaction"));
// Check that the block chain matches the known block chain up to a checkpoint
- if (!fTestNet)
- if ((nHeight == 11111 && hash != uint256("0x0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d")) ||
- (nHeight == 33333 && hash != uint256("0x000000002dd5588a74784eaa7ab0507a18ad16a236e7b1ce69f00d7ddfb5d0a6")) ||
- (nHeight == 68555 && hash != uint256("0x00000000001e1b4903550a0b96e9a9405c8a95f387162e4944e8d9fbe501cd6a")) ||
- (nHeight == 70567 && hash != uint256("0x00000000006a49b14bcf27462068f1264c961f11fa2e0eddd2be0791e1d4124a")) ||
- (nHeight == 74000 && hash != uint256("0x0000000000573993a3c9e41ce34471c079dcf5f52a0e824a81e7f953b8661a20")) ||
- (nHeight == 105000 && hash != uint256("0x00000000000291ce28027faea320c8d2b054b2e0fe44a773f3eefb151d6bdc97")) ||
- (nHeight == 118000 && hash != uint256("0x000000000000774a7f8a7a12dc906ddb9e17e75d684f15e00f8767f9e8f36553")) ||
- (nHeight == 134444 && hash != uint256("0x00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe")) ||
- (nHeight == 140700 && hash != uint256("0x000000000000033b512028abb90e1626d8b346fd0ed598ac0a3c371138dce2bd")))
- return DoS(100, error("AcceptBlock() : rejected by checkpoint lockin at %d", nHeight));
+ if (!Checkpoints::CheckBlock(nHeight, hash))
+ return DoS(100, error("AcceptBlock() : rejected by checkpoint lockin at %d", nHeight));
// Write block to history file
if (!CheckDiskSpace(::GetSerializeSize(*this, SER_DISK)))
return error("AcceptBlock() : AddToBlockIndex failed");
// Relay inventory, but don't relay old inventory during initial block download
+ int nBlockEstimate = Checkpoints::GetTotalBlocksEstimate();
if (hashBestChain == hash)
CRITICAL_BLOCK(cs_vNodes)
BOOST_FOREACH(CNode* pnode, vNodes)
- if (nBestHeight > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : 140700))
+ if (nBestHeight > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : nBlockEstimate))
pnode->PushInventory(CInv(MSG_BLOCK, hash));
return true;
if (!pblock->CheckBlock())
return error("ProcessBlock() : CheckBlock FAILED");
+ CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint(mapBlockIndex);
+ if (pcheckpoint && pblock->hashPrevBlock != hashBestChain)
+ {
+ // Extra checks to prevent "fill up memory by spamming with bogus blocks"
+ int64 deltaTime = pblock->GetBlockTime() - pcheckpoint->nTime;
+ if (deltaTime < 0)
+ {
+ if (pfrom)
+ pfrom->Misbehaving(100);
+ return error("ProcessBlock() : block with timestamp before last checkpoint");
+ }
+ CBigNum bnNewBlock;
+ bnNewBlock.SetCompact(pblock->nBits);
+ CBigNum bnRequired;
+ bnRequired.SetCompact(ComputeMinWork(pcheckpoint->nBits, deltaTime));
+ if (bnNewBlock > bnRequired)
+ {
+ if (pfrom)
+ pfrom->Misbehaving(100);
+ return error("ProcessBlock() : block with too little proof-of-work");
+ }
+ }
+
+
// If don't already have its previous block, shunt it off to holding area until we get it
if (!mapBlockIndex.count(pblock->hashPrevBlock))
{
}
// Ask the first connected node for block updates
- static int nAskedForBlocks;
+ static int nAskedForBlocks = 0;
if (!pfrom->fClient &&
(pfrom->nVersion < 32000 || pfrom->nVersion >= 32400) &&
(nAskedForBlocks < 1 || vNodes.size() <= 1))
{
printf("storing orphan tx %s\n", inv.hash.ToString().substr(0,10).c_str());
AddOrphanTx(vMsg);
+
+ // DoS prevention: do not allow mapOrphanTransactions to grow unbounded
+ int nEvicted = LimitOrphanTxSize(MAX_ORPHAN_TRANSACTIONS);
+ if (nEvicted > 0)
+ printf("mapOrphan overflow, removed %d tx\n", nEvicted);
}
if (tx.nDoS) pfrom->Misbehaving(tx.nDoS);
}
unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK);
if (nBlockSize + nTxSize >= MAX_BLOCK_SIZE_GEN)
continue;
+
+ // Legacy limits on sigOps:
int nTxSigOps = tx.GetSigOpCount();
if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS)
continue;
// Transaction fee required depends on block size
bool fAllowFree = (nBlockSize + nTxSize < 4000 || CTransaction::AllowFree(dPriority));
- int64 nMinFee = tx.GetMinFee(nBlockSize, fAllowFree, true);
+ int64 nMinFee = tx.GetMinFee(nBlockSize, fAllowFree);
// Connecting shouldn't fail due to dependency on other memory pool transactions
// because we're already processing them in order of dependency
map<uint256, CTxIndex> mapTestPoolTmp(mapTestPool);
- if (!tx.ConnectInputs(txdb, mapTestPoolTmp, CDiskTxPos(1,1,1), pindexPrev, nFees, false, true, nMinFee))
+ bool fInvalid;
+ MapPrevTx mapInputs;
+ if (!tx.FetchInputs(txdb, mapTestPoolTmp, false, true, mapInputs, fInvalid))
+ continue;
+
+ int64 nTxFees = tx.GetValueIn(mapInputs)-tx.GetValueOut();
+ if (nTxFees < nMinFee)
continue;
+
+ nTxSigOps += tx.GetP2SHSigOpCount(mapInputs);
+ if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS)
+ continue;
+
+ if (!tx.ConnectInputs(mapInputs, mapTestPoolTmp, CDiskTxPos(1,1,1), pindexPrev, false, true))
+ continue;
+ mapTestPoolTmp[tx.GetHash()] = CTxIndex(CDiskTxPos(1,1,1), tx.vout.size());
swap(mapTestPool, mapTestPoolTmp);
// Added
pblock->vtx.push_back(tx);
nBlockSize += nTxSize;
nBlockSigOps += nTxSigOps;
+ nFees += nTxFees;
// Add transactions that depend on this one to the priority queue
uint256 hash = tx.GetHash();
// Fill in header
pblock->hashPrevBlock = pindexPrev->GetBlockHash();
pblock->hashMerkleRoot = pblock->BuildMerkleTree();
- pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
- pblock->nBits = GetNextWorkRequired(pindexPrev);
+ pblock->UpdateTime(pindexPrev);
+ pblock->nBits = GetNextWorkRequired(pindexPrev, pblock.get());
pblock->nNonce = 0;
return pblock.release();
FormatHashBuffers(pblock.get(), pmidstate, pdata, phash1);
unsigned int& nBlockTime = *(unsigned int*)(pdata + 64 + 4);
+ unsigned int& nBlockBits = *(unsigned int*)(pdata + 64 + 8);
unsigned int& nBlockNonce = *(unsigned int*)(pdata + 64 + 12);
break;
// Update nTime every few seconds
- pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
+ pblock->UpdateTime(pindexPrev);
nBlockTime = ByteReverse(pblock->nTime);
+ if (fTestNet)
+ {
+ // Changing pblock->nTime can change work required on testnet:
+ nBlockBits = ByteReverse(pblock->nBits);
+ hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256();
+ }
}
}
}
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2011 The Bitcoin developers
+// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_MAIN_H
static const unsigned int MAX_BLOCK_SIZE = 1000000;
static const unsigned int MAX_BLOCK_SIZE_GEN = MAX_BLOCK_SIZE/2;
static const int MAX_BLOCK_SIGOPS = MAX_BLOCK_SIZE/50;
+static const int MAX_ORPHAN_TRANSACTIONS = MAX_BLOCK_SIZE/100;
static const int64 COIN = 100000000;
static const int64 CENT = 1000000;
static const int64 MIN_TX_FEE = 50000;
void FormatHashBuffers(CBlock* pblock, char* pmidstate, char* pdata, char* phash1);
bool CheckWork(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey);
bool CheckProofOfWork(uint256 hash, unsigned int nBits);
-int GetTotalBlocksEstimate();
+unsigned int ComputeMinWork(unsigned int nBase, int64 nTime);
int GetNumBlocksOfPeers();
bool IsInitialBlockDownload();
std::string GetWarnings(std::string strFor);
};
+typedef std::map<uint256, std::pair<CTxIndex, CTransaction> > MapPrevTx;
//
return n;
}
+ /** Count ECDSA signature operations in pay-to-script-hash inputs.
+ This is a better measure of how expensive it is to process this transaction.
+
+ @param[in] mapInputsMap of previous transactions that have outputs we're spending
+ @return maximum number of sigops required to validate this transaction's inputs
+ @see CTransaction::FetchInputs
+ */
+ int GetP2SHSigOpCount(const MapPrevTx& mapInputs) const;
+
bool IsStandard() const
{
BOOST_FOREACH(const CTxIn& txin, vin)
return nValueOut;
}
+ /** Amount of bitcoins coming in to this transaction
+ Note that lightweight clients may not know anything besides the hash of previous transactions,
+ so may not be able to calculate this.
+
+ @param[in] mapInputsMap of previous transactions that have outputs we're spending
+ @returnSum of value of all inputs (scriptSigs)
+ @see CTransaction::FetchInputs
+ */
+ int64 GetValueIn(const MapPrevTx& mapInputs) const;
+
static bool AllowFree(double dPriority)
{
// Large (in bytes) low-priority (new, small-coin) transactions
bool ReadFromDisk(CTxDB& txdb, COutPoint prevout);
bool ReadFromDisk(COutPoint prevout);
bool DisconnectInputs(CTxDB& txdb);
- bool ConnectInputs(CTxDB& txdb, std::map<uint256, CTxIndex>& mapTestPool, CDiskTxPos posThisTx,
- CBlockIndex* pindexBlock, int64& nFees, bool fBlock, bool fMiner, int64 nMinFee=0);
+
+ /** Fetch from memory and/or disk. inputsRet keys are transaction hashes.
+
+ @param[in] txdb Transaction database
+ @param[in] mapTestPool List of pending changes to the transaction index database
+ @param[in] fBlock True if being called to add a new best-block to the chain
+ @param[in] fMiner True if being called by CreateNewBlock
+ @param[out] inputsRet Pointers to this transaction's inputs
+ @param[out] fInvalid returns true if transaction is invalid
+ @return Returns true if all inputs are in txdb or mapTestPool
+ */
+ bool FetchInputs(CTxDB& txdb, const std::map<uint256, CTxIndex>& mapTestPool,
+ bool fBlock, bool fMiner, MapPrevTx& inputsRet, bool& fInvalid);
+
+ /** Sanity check previous transactions, then, if all checks succeed,
+ mark them as spent by this transaction.
+
+ @param[in] inputsPrevious transactions (from FetchInputs)
+ @param[out] mapTestPoolKeeps track of inputs that need to be updated on disk
+ @param[in] posThisTxPosition of this transaction on disk
+ @param[in] pindexBlock
+ @param[in] fBlock true if called from ConnectBlock
+ @param[in] fMiner true if called from CreateNewBlock
+ @param[in] fStrictPayToScriptHash true if fully validating p2sh transactions
+ @return Returns true if all checks succeed
+ */
+ bool ConnectInputs(MapPrevTx inputs,
+ std::map<uint256, CTxIndex>& mapTestPool, const CDiskTxPos& posThisTx,
+ const CBlockIndex* pindexBlock, bool fBlock, bool fMiner, bool fStrictPayToScriptHash=true);
bool ClientConnectInputs();
bool CheckTransaction() const;
bool AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs=true, bool* pfMissingInputs=NULL);
bool AcceptToMemoryPool(bool fCheckInputs=true, bool* pfMissingInputs=NULL);
protected:
+ const CTxOut& GetOutputFor(const CTxIn& input, const MapPrevTx& inputs) const;
bool AddToMemoryPoolUnchecked();
public:
bool RemoveFromMemoryPool();
return n;
}
+ void UpdateTime(const CBlockIndex* pindexPrev);
+
uint256 BuildMerkleTree() const
{
HEADERS = \
base58.h \
bignum.h \
+ checkpoints.h \
crypter.h \
db.h \
headers.h \
LIBS += -l mingwthrd -l kernel32 -l user32 -l gdi32 -l comdlg32 -l winspool -l winmm -l shell32 -l comctl32 -l ole32 -l oleaut32 -l uuid -l rpcrt4 -l advapi32 -l ws2_32 -l shlwapi
OBJS= \
+ obj/checkpoints.o \
obj/crypter.o \
obj/db.o \
obj/init.o \
HEADERS = \
base58.h \
bignum.h \
+ checkpoints.h \
crypter.h \
db.h \
headers.h \
LIBS += -l kernel32 -l user32 -l gdi32 -l comdlg32 -l winspool -l winmm -l shell32 -l comctl32 -l ole32 -l oleaut32 -l uuid -l rpcrt4 -l advapi32 -l ws2_32 -l shlwapi
OBJS= \
+ obj/checkpoints.o \
obj/crypter.o \
obj/db.o \
obj/init.o \
LIBS= -dead_strip
ifdef STATIC
# Build STATIC if you are redistributing the bitcoind binary
+TESTLIBS += \
+ $(DEPSDIR)/lib/libboost_unit_test_framework-mt.a
LIBS += \
$(DEPSDIR)/lib/db48/libdb_cxx-4.8.a \
$(DEPSDIR)/lib/libboost_system-mt.a \
$(DEPSDIR)/lib/libboost_program_options-mt.a \
$(DEPSDIR)/lib/libboost_thread-mt.a \
$(DEPSDIR)/lib/libssl.a \
- $(DEPSDIR)/lib/libcrypto.a
+ $(DEPSDIR)/lib/libcrypto.a \
+ -lz
else
+TESTLIBS += \
+ -lboost_unit_test_framework-mt
LIBS += \
-ldb_cxx-4.8 \
-lboost_system-mt \
-lboost_program_options-mt \
-lboost_thread-mt \
-lssl \
- -lcrypto
+ -lcrypto \
+ -lz
+TESTDEFS += -DBOOST_TEST_DYN_LINK
endif
DEFS=-DMAC_OSX -DMSG_NOSIGNAL=0 -DUSE_SSL
HEADERS = \
base58.h \
bignum.h \
+ checkpoints.h \
crypter.h \
db.h \
headers.h \
wallet.h
OBJS= \
+ obj/checkpoints.o \
obj/crypter.o \
obj/db.o \
obj/init.o \
# auto-generated dependencies:
-include obj/nogui/*.P
--include obj/test/*.P
+-include obj-test/*.P
obj/nogui/%.o: %.cpp
$(CXX) -c $(CFLAGS) -MMD -o $@ $<
$(CXX) $(CFLAGS) -o $@ $(LIBPATHS) $^ $(LIBS)
obj/test/%.o: test/%.cpp
- $(CXX) -c $(CFLAGS) -MMD -o $@ $<
+ $(CXX) -c $(TESTDEFS) $(CFLAGS) -MMD -o $@ $<
@cp $(@:%.o=%.d) $(@:%.o=%.P); \
sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \
-e '/^$$/ d' -e 's/$$/ :/' < $(@:%.o=%.d) >> $(@:%.o=%.P); \
rm -f $(@:%.o=%.d)
test_bitcoin: obj/test/test_bitcoin.o $(filter-out obj/nogui/init.o,$(OBJS:obj/%=obj/nogui/%))
- $(CXX) $(CFLAGS) -o $@ $(LIBPATHS) $^ $(LIBS) $(DEPSDIR)/lib/libboost_unit_test_framework-mt.a
+ $(CXX) $(CFLAGS) -o $@ $(LIBPATHS) $^ $(LIBS) $(TESTLIBS)
clean:
-rm -f bitcoind test_bitcoin
-rm -f obj/*.o
-rm -f obj/nogui/*.o
- -rm -f obj/test/*.o
+ -rm -f obj-test/*.o
-rm -f obj/*.P
-rm -f obj/nogui/*.P
- -rm -f obj/test/*.P
+ -rm -f obj-test/*.P
DEFS=-DNOPCH
DEFS += $(addprefix -I,$(BOOST_INCLUDE_PATH) $(BDB_INCLUDE_PATH) $(OPENSSL_INCLUDE_PATH))
-LIBS += $(addprefix -l,$(BOOST_LIB_PATH) $(BDB_LIB_PATH) $(OPENSSL_LIB_PATH))
+LIBS = $(addprefix -L,$(BOOST_LIB_PATH) $(BDB_LIB_PATH) $(OPENSSL_LIB_PATH))
LMODE = dynamic
LMODE2 = dynamic
ifeq (${STATIC}, all)
LMODE2 = static
endif
+else
+ TESTDEFS += -DBOOST_TEST_DYN_LINK
endif
# for boost 1.37, add -mt to the boost libraries
-LIBS= \
+LIBS += \
-Wl,-B$(LMODE) \
-l boost_system$(BOOST_LIB_SUFFIX) \
-l boost_filesystem$(BOOST_LIB_SUFFIX) \
HEADERS = \
base58.h \
bignum.h \
+ checkpoints.h \
crypter.h \
db.h \
headers.h \
wallet.h
OBJS= \
+ obj/checkpoints.o \
obj/crypter.o \
obj/db.o \
obj/init.o \
# auto-generated dependencies:
-include obj/nogui/*.P
--include obj/test/*.P
+-include obj-test/*.P
obj/nogui/%.o: %.cpp
$(CXX) -c $(xCXXFLAGS) -MMD -o $@ $<
bitcoind: $(OBJS:obj/%=obj/nogui/%)
$(CXX) $(xCXXFLAGS) -o $@ $^ $(LDFLAGS) $(LIBS)
-obj/test/%.o: test/%.cpp
- $(CXX) -c $(xCXXFLAGS) -MMD -o $@ $<
+obj-test/%.o: test/%.cpp
+ $(CXX) -c $(TESTDEFS) $(xCXXFLAGS) -MMD -o $@ $<
@cp $(@:%.o=%.d) $(@:%.o=%.P); \
sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \
-e '/^$$/ d' -e 's/$$/ :/' < $(@:%.o=%.d) >> $(@:%.o=%.P); \
rm -f $(@:%.o=%.d)
-test_bitcoin: obj/test/test_bitcoin.o $(filter-out obj/nogui/init.o,$(OBJS:obj/%=obj/nogui/%))
- $(CXX) $(xCXXFLAGS) -o $@ $(LIBPATHS) $^ -Wl,-Bstatic -lboost_unit_test_framework $(LDFLAGS) $(LIBS)
+test_bitcoin: obj-test/test_bitcoin.o $(filter-out obj/nogui/init.o,$(OBJS:obj/%=obj/nogui/%))
+ $(CXX) $(xCXXFLAGS) -o $@ $(LIBPATHS) $^ -Wl,-B$(LMODE) -lboost_unit_test_framework $(LDFLAGS) $(LIBS)
clean:
-rm -f bitcoind test_bitcoin
-rm -f obj/*.o
-rm -f obj/nogui/*.o
- -rm -f obj/test/*.o
+ -rm -f obj-test/*.o
-rm -f obj/*.P
-rm -f obj/nogui/*.P
- -rm -f obj/test/*.P
+ -rm -f obj-test/*.P
HEADERS = \
base58.h \
bignum.h \
+ checkpoints.h \
crypter.h \
db.h \
headers.h \
wallet.h
OBJS= \
+ obj\checkpoints.o \
obj\crypter.o \
obj\db.o \
obj\init.o \
.cpp{obj}.obj:
cl $(CFLAGS) /DGUI /Fo$@ %s
+obj\checkpoints.obj: $(HEADERS)
+
obj\util.obj: $(HEADERS)
obj\script.obj: $(HEADERS)
.cpp{obj\nogui}.obj:
cl $(CFLAGS) /Fo$@ %s
+obj\nogui\checkpoints.obj: $(HEADERS)
+
obj\nogui\util.obj: $(HEADERS)
obj\nogui\script.obj: $(HEADERS)
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2011 The Bitcoin developers
+// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
#ifdef USE_UPNP
void ThreadMapPort2(void* parg);
#endif
+void ThreadDNSAddressSeed2(void* parg);
bool OpenNetworkConnection(const CAddress& addrConnect);
void AddressCurrentlyConnected(const CAddress& addr)
{
+ CAddress *paddrFound = NULL;
+
CRITICAL_BLOCK(cs_mapAddresses)
{
// Only if it's been published already
map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
if (it != mapAddresses.end())
+ paddrFound = &(*it).second;
+ }
+
+ if (paddrFound)
+ {
+ int64 nUpdateInterval = 20 * 60;
+ if (paddrFound->nTime < GetAdjustedTime() - nUpdateInterval)
{
- CAddress& addrFound = (*it).second;
- int64 nUpdateInterval = 20 * 60;
- if (addrFound.nTime < GetAdjustedTime() - nUpdateInterval)
- {
- // Periodically update most recently seen time
- addrFound.nTime = GetAdjustedTime();
- CAddrDB addrdb;
- addrdb.WriteAddress(addrFound);
- }
+ // Periodically update most recently seen time
+ paddrFound->nTime = GetAdjustedTime();
+ CAddrDB addrdb;
+ addrdb.WriteAddress(*paddrFound);
}
}
}
printf("disconnecting node %s\n", addr.ToString().c_str());
closesocket(hSocket);
hSocket = INVALID_SOCKET;
+ vRecv.clear();
}
}
struct sockaddr_in sockaddr;
socklen_t len = sizeof(sockaddr);
SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len);
- CAddress addr(sockaddr);
+ CAddress addr;
int nInbound = 0;
+ if (hSocket != INVALID_SOCKET)
+ addr = CAddress(sockaddr);
+
CRITICAL_BLOCK(cs_vNodes)
BOOST_FOREACH(CNode* pnode, vNodes)
if (pnode->fInbound)
nInbound++;
+
if (hSocket == INVALID_SOCKET)
{
if (WSAGetLastError() != WSAEWOULDBLOCK)
}
else if (CNode::IsBanned(addr.ip))
{
- printf("connetion from %s dropped (banned)\n", addr.ToString().c_str());
+ printf("connection from %s dropped (banned)\n", addr.ToString().c_str());
closesocket(hSocket);
}
else
char port[6];
sprintf(port, "%d", GetListenPort());
- const char * rootdescurl = 0;
const char * multicastif = 0;
const char * minissdpdpath = 0;
- int error = 0;
struct UPNPDev * devlist = 0;
char lanaddr[64];
+#ifndef UPNPDISCOVER_SUCCESS
+ /* miniupnpc 1.5 */
+ devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0);
+#else
+ /* miniupnpc 1.6 */
+ int error = 0;
devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error);
+#endif
struct UPNPUrls urls;
struct IGDdatas data;
r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
if (r == 1)
{
- char intClient[16];
- char intPort[6];
+ if (!addrLocalHost.IsRoutable())
+ {
+ char externalIPAddress[40];
+ r = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIPAddress);
+ if(r != UPNPCOMMAND_SUCCESS)
+ printf("UPnP: GetExternalIPAddress() returned %d\n", r);
+ else
+ {
+ if(externalIPAddress[0])
+ {
+ printf("UPnP: ExternalIPAddress = %s\n", externalIPAddress);
+ CAddress addrExternalFromUPnP(externalIPAddress, 0, false, nLocalServices);
+ if (addrExternalFromUPnP.IsRoutable())
+ addrLocalHost = addrExternalFromUPnP;
+ }
+ else
+ printf("UPnP: GetExternalIPAddress failed.\n");
+ }
+ }
+
string strDesc = "Bitcoin " + FormatFullVersion();
+#ifndef UPNPDISCOVER_SUCCESS
+ /* miniupnpc 1.5 */
r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
- port, port, lanaddr, strDesc.c_str(), "TCP", 0, "0");
+ port, port, lanaddr, strDesc.c_str(), "TCP", 0);
+#else
+ /* miniupnpc 1.6 */
+ r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
+ port, port, lanaddr, strDesc.c_str(), "TCP", 0, "0");
+#endif
if(r!=UPNPCOMMAND_SUCCESS)
printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
port, port, lanaddr, r, strupnperror(r));
else
printf("UPnP Port Mapping successful.\n");
+ int i = 1;
loop {
if (fShutdown || !fUseUPnP)
{
FreeUPNPUrls(&urls);
return;
}
+ if (i % 600 == 0) // Refresh every 20 minutes
+ {
+#ifndef UPNPDISCOVER_SUCCESS
+ /* miniupnpc 1.5 */
+ r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
+ port, port, lanaddr, strDesc.c_str(), "TCP", 0);
+#else
+ /* miniupnpc 1.6 */
+ r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
+ port, port, lanaddr, strDesc.c_str(), "TCP", 0, "0");
+#endif
+
+ if(r!=UPNPCOMMAND_SUCCESS)
+ printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
+ port, port, lanaddr, r, strupnperror(r));
+ else
+ printf("UPnP Port Mapping successful.\n");;
+ }
Sleep(2000);
+ i++;
}
} else {
printf("No valid UPnP IGDs found\n");
static const char *strDNSSeed[] = {
"bitseed.xf2.org",
"dnsseed.bluematt.me",
+ "seed.bitcoin.sipa.be",
+ "dnsseed.bitcoin.dashjr.org",
};
-void DNSAddressSeed()
+void ThreadDNSAddressSeed(void* parg)
{
+ IMPLEMENT_RANDOMIZE_STACK(ThreadDNSAddressSeed(parg));
+ try
+ {
+ vnThreadsRunning[6]++;
+ ThreadDNSAddressSeed2(parg);
+ vnThreadsRunning[6]--;
+ }
+ catch (std::exception& e) {
+ vnThreadsRunning[6]--;
+ PrintException(&e, "ThreadDNSAddressSeed()");
+ } catch (...) {
+ vnThreadsRunning[6]--;
+ throw; // support pthread_cancel()
+ }
+ printf("ThreadDNSAddressSeed exiting\n");
+}
+
+void ThreadDNSAddressSeed2(void* parg)
+{
+ printf("ThreadDNSAddressSeed started\n");
int found = 0;
if (!fTestNet)
{
printf("Loading addresses from DNS seeds (could take a while)\n");
- CAddrDB addrDB;
- addrDB.TxnBegin();
for (int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) {
vector<CAddress> vaddr;
if (Lookup(strDNSSeed[seed_idx], vaddr, NODE_NETWORK, -1, true))
{
+ CAddrDB addrDB;
+ addrDB.TxnBegin();
BOOST_FOREACH (CAddress& addr, vaddr)
{
if (addr.GetByte(3) != 127)
found++;
}
}
+ addrDB.TxnCommit(); // Save addresses (it's ok if this fails)
}
}
-
- addrDB.TxnCommit(); // Save addresses (it's ok if this fails)
}
printf("%d addresses found from DNS seeds\n", found);
+
+
+
+
+
+
+
+
+
unsigned int pnSeed[] =
{
- 0x6884ac63, 0x3ffecead, 0x2919b953, 0x0942fe50, 0x7a1d922e, 0xcdd6734a, 0x953a5bb6, 0x2c46922e,
- 0xe2a5f143, 0xaa39103a, 0xa06afa5c, 0x135ffd59, 0xe8e82863, 0xf61ef029, 0xf75f042e, 0x2b363532,
- 0x29b2df42, 0x16b1f64e, 0xd46e281b, 0x5280bf58, 0x60372229, 0x1be58e4f, 0xa8496f45, 0x1fb1a057,
- 0x756b3844, 0x3bb79445, 0x0b375518, 0xcccb0102, 0xb682bf2e, 0x46431c02, 0x3a81073a, 0xa3771f1f,
- 0x213a121f, 0x85dc2c1b, 0x56b4323b, 0xb34e8945, 0x3c40b33d, 0xfa276418, 0x1f818d29, 0xebe1e344,
- 0xf6160a18, 0xf4fa384a, 0x34b09558, 0xb882b543, 0xe3ce2253, 0x6abf56d8, 0xe91b1155, 0x688ee6ad,
- 0x2efc6058, 0x4792cd47, 0x0c32f757, 0x4c813a46, 0x8c93644a, 0x37507444, 0x813ad218, 0xdac06d4a,
- 0xe4c63e4b, 0x21a1ea3c, 0x8d88556f, 0x30e9173a, 0x041f681b, 0xdc77ba50, 0xc0072753, 0xceddd44f,
- 0x052d1743, 0xe3c77a4a, 0x13981c3a, 0x5685d918, 0x3c0e4e70, 0x3e56fb54, 0xb676ae0c, 0xac93c859,
- 0x22279f43, 0x975a4542, 0xe527f071, 0xea162f2e, 0x3c65a32e, 0x5be5713b, 0x961ec418, 0xb202922e,
- 0x5ef7be50, 0xce49f53e, 0x05803b47, 0x8463b055, 0x78576153, 0x3ec2ae3a, 0x4bbd7118, 0xafcee043,
- 0x56a3e8ba, 0x6174de4d, 0x8d01ba4b, 0xc9af564e, 0xdbc9c547, 0xa627474d, 0xdada9244, 0xd3b3083a,
- 0x523e071f, 0xd6b96f18, 0xbd527c46, 0xdf2bbb4d, 0xd37b4a4b, 0x3a6a2158, 0xc064b055, 0x18a8e055,
- 0xec4dae3b, 0x0540416c, 0x475b4fbe, 0x064803b2, 0x48e9f062, 0x2898524b, 0xd315ff43, 0xf786d247,
- 0xc7ea2f3e, 0xc087f043, 0xc163354b, 0x8250284d, 0xed300029, 0xbf36e05c, 0x8eb3ae4c, 0xe7aa623e,
- 0x7ced0274, 0xdd362c1b, 0x362b995a, 0xca26b629, 0x3fc41618, 0xb97b364e, 0xa05b8729, 0x0f5e3c43,
- 0xdf942618, 0x6aeb9b5b, 0xbf04762e, 0xfaaeb118, 0x87579958, 0x76520044, 0xc2660c5b, 0x628b201b,
- 0xf193932e, 0x1c0ad045, 0xff908346, 0x8da9d4da, 0xed201c1f, 0xa47a2b1b, 0x330007d4, 0x8ba1ed47,
- 0xb2f02d44, 0x7db62c1b, 0x781c454b, 0xc0300029, 0xb7062a45, 0x88b52e3a, 0x78dd6b63, 0x1cb9b718,
- 0x5d358e47, 0x59912c3b, 0x79607544, 0x5197f759, 0xc023be48, 0xd1013743, 0x0f354057, 0x8e3aac3b,
- 0x4114693e, 0x22316318, 0xe27dda50, 0x878eac3b, 0x4948a21f, 0x5db7f24c, 0x8ccb6157, 0x26a5de18,
- 0x0a11bd43, 0x27bb1e41, 0x60a7a951, 0x3e16b35e, 0x07888b53, 0x5648a853, 0x0149fe50, 0xd070a34f,
- 0x6454c96d, 0xd6e54758, 0xa96dc152, 0x65447861, 0xf6bdf95e, 0x10400202, 0x2c29d483, 0x18174732,
- 0x1d840618, 0x12e61818, 0x089d3f3c, 0x917e931f, 0xd1b0c90e, 0x25bd3c42, 0xeb05775b, 0x7d550c59,
- 0x6cfacb01, 0xe4224444, 0xa41dd943, 0x0f5aa643, 0x5e33731b, 0x81036d50, 0x6f46a0d1, 0x7731be43,
- 0x14840e18, 0xf1e8d059, 0x661d2b1f, 0x40a3201b, 0x9407b843, 0xedf0254d, 0x7bd1a5bc, 0x073dbe51,
- 0xe864a97b, 0x2efd947b, 0xb9ca0e45, 0x4e2113ad, 0xcc305731, 0xd39ca63c, 0x733df918, 0xda172b1f,
- 0xaa03b34d, 0x7230fd4d, 0xf1ce6e3a, 0x2e9fab43, 0xa4010750, 0xa928bd18, 0x6809be42, 0xb19de348,
- 0xff956270, 0x0d795f51, 0xd2dec247, 0x6df5774b, 0xbac11f79, 0xdfb05c75, 0x887683d8, 0xa1e83632,
- 0x2c0f7671, 0x28bcb65d, 0xac2a7545, 0x3eebfc60, 0x304ad7c4, 0xa215a462, 0xc86f0f58, 0xcfb92ebe,
- 0x5e23ed82, 0xf506184b, 0xec0f19b7, 0x060c59ad, 0x86ee3174, 0x85380774, 0xa199a562, 0x02b507ae,
- 0x33eb2163, 0xf2112b1f, 0xb702ba50, 0x131b9618, 0x90ccd04a, 0x08f3273b, 0xecb61718, 0x64b8b44d,
- 0x182bf4dc, 0xc7b68286, 0x6e318d5f, 0xfdb03654, 0xb3272e54, 0xe014ad4b, 0x274e4a31, 0x7806375c,
- 0xbc34a748, 0x1b5ad94a, 0x6b54d10e, 0x73e2ae6e, 0x5529d483, 0x8455a76d, 0x99c13f47, 0x1d811741,
- 0xa9782a78, 0x0b00464d, 0x7266ea50, 0x532dab46, 0x33e1413e, 0x780d0c18, 0x0fb0854e, 0x03370155,
- 0x2693042e, 0xfa3d824a, 0x2bb1681b, 0x37ea2a18, 0x7fb8414b, 0x32e0713b, 0xacf38d3f, 0xa282716f,
- 0xb1a09d7b, 0xa04b764b, 0x83c94d18, 0x05ee4c6d, 0x0e795f51, 0x46984352, 0xf80fc247, 0x3fccb946,
- 0xd7ae244b, 0x0a8e0a4c, 0x57b141bc, 0x3647bed1, 0x1431b052, 0x803a8bbb, 0xfc69056b, 0xf5991862,
- 0x14963b2e, 0xd35d5dda, 0xc6c73574, 0xc8f1405b, 0x0ca4224d, 0xecd36071, 0xa9461754, 0xe7a0ed72,
- 0x559e8346, 0x1c9beec1, 0xc786ea4a, 0x9561b44d, 0x9788074d, 0x1a69934f, 0x23c5614c, 0x07c79d4b,
- 0xc7ee52db, 0xc72df351, 0xcb135e44, 0xa0988346, 0xc211fc4c, 0x87dec34b, 0x1381074d, 0x04a65cb7,
- 0x4409083a, 0x4a407a4c, 0x92b8d37d, 0xacf50b4d, 0xa58aa5bc, 0x448f801f, 0x9c83762e, 0x6fd5734a,
- 0xfe2d454b, 0x84144c55, 0x05190e4c, 0xb2151448, 0x63867a3e, 0x16099018, 0x9c010d3c, 0x962d8f3d,
- 0xd51ee453, 0x9d86801f, 0x68e87b47, 0x6bf7bb73, 0x5fc7910e, 0x10d90118, 0x3db04442, 0x729d3e4b,
- 0xc397d842, 0x57bb15ad, 0x72f31f4e, 0xc9380043, 0x2bb24e18, 0xd9b8ab50, 0xb786801f, 0xf4dc4847,
- 0x85f4bb51, 0x4435995b, 0x5ba07e40, 0x2c57392e, 0x3628124b, 0x9839b64b, 0x6fe8b24d, 0xaddce847,
- 0x75260e45, 0x0c572a43, 0xfea21902, 0xb9f9742e, 0x5a70d443, 0x8fc5910e, 0x868d4744, 0x56245e02,
- 0xd7eb5f02, 0x35c12c1b, 0x4373034b, 0x8786554c, 0xa6facf18, 0x4b11a31f, 0x3570664e, 0x5a64bc42,
- 0x0b03983f, 0x8f457e4c, 0x0fd874c3, 0xb6cf31b2, 0x2bbc2d4e, 0x146ca5b2, 0x9d00b150, 0x048a4153,
- 0xca4dcd43, 0xc1607cca, 0x8234cf57, 0x9c7daead, 0x3dc07658, 0xea5c6e4c, 0xf1a0084e, 0x16d2ee53,
- 0x1b849418, 0xfe913a47, 0x1e988f62, 0x208b644c, 0xc55ee980, 0xbdbce747, 0xf59a384e, 0x0f56091b,
- 0x7417b745, 0x0c37344e, 0x2c62ab47, 0xf8533a4d, 0x8030084d, 0x76b93c4b, 0xda6ea0ad, 0x3c54f618,
- 0x63b0de1f, 0x7370d858, 0x1a70bb4c, 0xdda63b2e, 0x60b2ba50, 0x1ba7d048, 0xbe1b2c1b, 0xabea5747,
- 0x29ad2e4d, 0xe8cd7642, 0x66c80e18, 0x138bf34a, 0xc6145e44, 0x2586794c, 0x07bc5478, 0x0da0b14d,
- 0x8f95354e, 0x9eb11c62, 0xa1545e46, 0x2e7a2602, 0x408c9c3d, 0x59065d55, 0xf51d1a4c, 0x3bbc6a4e,
- 0xc71b2a2e, 0xcdaaa545, 0x17d659d0, 0x5202e7ad, 0xf1b68445, 0x93375961, 0xbd88a043, 0x066ad655,
- 0x890f6318, 0x7b7dca47, 0x99bdd662, 0x3bb4fc53, 0x1231efdc, 0xc0a99444, 0x96bbea47, 0x61ed8748,
- 0x27dfa73b, 0x8d4d1754, 0x3460042e, 0x551f0c4c, 0x8d0e0718, 0x162ddc53, 0x53231718, 0x1ecd65d0,
- 0x944d28bc, 0x3b79d058, 0xaff97fbc, 0x4860006c, 0xc101c90e, 0xace41743, 0xa5975d4c, 0x5cc2703e,
- 0xb55a4450, 0x02d18840, 0xee2765ae, 0xd6012fd5, 0x24c94d7d, 0x8c6eec47, 0x7520ba5d, 0x9e15e460,
- 0x8510b04c, 0x75ec3847, 0x1dfa6661, 0xe172b3ad, 0x5744c90e, 0x52a0a152, 0x8d6fad18, 0x67b74b6d,
- 0x93a089b2, 0x0f3ac5d5, 0xe5de1855, 0x43d25747, 0x4bad804a, 0x55b408d8, 0x60a36441, 0xf553e860,
- 0xdb2fa2c8, 0x03152b32, 0xdd27a7d5, 0x3116a8b8, 0x0a1d708c, 0xeee2f13c, 0x6acf436f, 0xce6eb4ca,
- 0x101cd3d9, 0x1c48a6b8, 0xe57d6f44, 0x93dcf562,
+ 0x959bd347, 0xf8de42b2, 0x73bc0518, 0xea6edc50, 0x21b00a4d, 0xc725b43d, 0xd665464d, 0x1a2a770e,
+ 0x27c93946, 0x65b2fa46, 0xb80ae255, 0x66b3b446, 0xb1877a3e, 0x6ee89e3e, 0xc3175b40, 0x2a01a83c,
+ 0x95b1363a, 0xa079ad3d, 0xe6ca801f, 0x027f4f4a, 0x34f7f03a, 0xf790f04a, 0x16ca801f, 0x2f4d5e40,
+ 0x3a4d5e40, 0xc43a322e, 0xc8159753, 0x14d4724c, 0x7919a118, 0xe0bdb34e, 0x68a16b2e, 0xff64b44d,
+ 0x6099115b, 0x9b57b05b, 0x7bd1b4ad, 0xdf95944f, 0x29d2b73d, 0xafa8db79, 0xe247ba41, 0x24078348,
+ 0xf722f03c, 0x33567ebc, 0xace64ed4, 0x984d3932, 0xb5f34e55, 0x27b7024d, 0x94579247, 0x8894042e,
+ 0x9357d34c, 0x1063c24b, 0xcaa228b1, 0xa3c5a8b2, 0x5dc64857, 0xa2c23643, 0xa8369a54, 0x31203077,
+ 0x00707c5c, 0x09fc0b3a, 0x272e9e2e, 0xf80f043e, 0x9449ca3e, 0x5512c33e, 0xd106b555, 0xe8024157,
+ 0xe288ec29, 0xc79c5461, 0xafb63932, 0xdb02ab4b, 0x0e512777, 0x8a145a4c, 0xb201ff4f, 0x5e09314b,
+ 0xcd9bfbcd, 0x1c023765, 0x4394e75c, 0xa728bd4d, 0x65331552, 0xa98420b1, 0x89ecf559, 0x6e80801f,
+ 0xf404f118, 0xefd62b51, 0x05918346, 0x9b186d5f, 0xacabab46, 0xf912e255, 0xc188ea62, 0xcc55734e,
+ 0xc668064d, 0xd77a4558, 0x46201c55, 0xf17dfc80, 0xf7142f2e, 0x87bfb718, 0x8aa54fb2, 0xc451d518,
+ 0xc4ae8831, 0x8dd44d55, 0x5bbd206c, 0x64536b5d, 0x5c667e60, 0x3b064242, 0xfe963a42, 0xa28e6dc8,
+ 0xe8a9604a, 0xc989464e, 0xd124a659, 0x50065140, 0xa44dfe5e, 0x1079e655, 0x3fb986d5, 0x47895b18,
+ 0x7d3ce4ad, 0x4561ba50, 0x296eec62, 0x255b41ad, 0xaed35ec9, 0x55556f12, 0xc7d3154d, 0x3297b65d,
+ 0x8930121f, 0xabf42e4e, 0x4a29e044, 0x1212685d, 0x676c1e40, 0xce009744, 0x383a8948, 0xa2dbd0ad,
+ 0xecc2564d, 0x07dbc252, 0x887ee24b, 0x5171644c, 0x6bb798c1, 0x847f495d, 0x4cbb7145, 0x3bb81c32,
+ 0x45eb262e, 0xc8015a4e, 0x250a361b, 0xf694f946, 0xd64a183e, 0xd4f1dd59, 0x8f20ffd4, 0x51d9e55c,
+ 0x09521763, 0x5e02002e, 0x32c8074d, 0xe685762e, 0x8290b0bc, 0x762a922e, 0xfc5ee754, 0x83a24829,
+ 0x775b224d, 0x6295bb4d, 0x38ec0555, 0xbffbba50, 0xe5560260, 0x86b16a7c, 0xd372234e, 0x49a3c24b,
+ 0x2f6a171f, 0x4d75ed60, 0xae94115b, 0xcb543744, 0x63080c59, 0x3f9c724c, 0xc977ce18, 0x532efb18,
+ 0x69dc3b2e, 0x5f94d929, 0x1732bb4d, 0x9c814b4d, 0xe6b3762e, 0xc024f662, 0x8face35b, 0x6b5b044d,
+ 0x798c7b57, 0x79a6b44c, 0x067d3057, 0xf9e94e5f, 0x91cbe15b, 0x71405eb2, 0x2662234e, 0xcbcc4a6d,
+ 0xbf69d54b, 0xa79b4e55, 0xec6d3e51, 0x7c0b3c02, 0x60f83653, 0x24c1e15c, 0x1110b62e, 0x10350f59,
+ 0xa56f1d55, 0x3509e7a9, 0xeb128354, 0x14268e2e, 0x934e28bc, 0x8e32692e, 0x8331a21f, 0x3e633932,
+ 0xc812b12e, 0xc684bf2e, 0x80112d2e, 0xe0ddc96c, 0xc630ca4a, 0x5c09b3b2, 0x0b580518, 0xc8e9d54b,
+ 0xd169aa43, 0x17d0d655, 0x1d029963, 0x7ff87559, 0xcb701f1f, 0x6fa3e85d, 0xe45e9a54, 0xf05d1802,
+ 0x44d03b2e, 0x837b692e, 0xccd4354e, 0x3d6da13c, 0x3423084d, 0xf707c34a, 0x55f6db3a, 0xad26e442,
+ 0x6233a21f, 0x09e80e59, 0x8caeb54d, 0xbe870941, 0xb407d20e, 0x20b51018, 0x56fb152e, 0x460d2a4e,
+ 0xbb9a2946, 0x560eb12e, 0xed83dd29, 0xd6724f53, 0xa50aafb8, 0x451346d9, 0x88348e2e, 0x7312fead,
+ 0x8ecaf96f, 0x1bda4e5f, 0xf1671e40, 0x3c8c3e3b, 0x4716324d, 0xdde24ede, 0xf98cd17d, 0xa91d4644,
+ 0x28124eb2, 0x147d5129, 0xd022042e, 0x61733d3b, 0xad0d5e02, 0x8ce2932e, 0xe5c18502, 0x549c1e32,
+ 0x9685801f, 0x86e217ad, 0xd948214b, 0x4110f462, 0x3a2e894e, 0xbd35492e, 0x87e0d558, 0x64b8ef7d,
+ 0x7c3eb962, 0x72a84b3e, 0x7cd667c9, 0x28370a2e, 0x4bc60e7b, 0x6fc1ec60, 0x14a6983f, 0x86739a4b,
+ 0x46954e5f, 0x32e2e15c, 0x2e9326cf, 0xe5801c5e, 0x379607b2, 0x32151145, 0xf0e39744, 0xacb54c55,
+ 0xa37dfb60, 0x83b55cc9, 0x388f7ca5, 0x15034f5f, 0x3e94965b, 0x68e0ffad, 0x35280f59, 0x8fe190cf,
+ 0x7c6ba5b2, 0xa5e9db43, 0x4ee1fc60, 0xd9d94e5f, 0x04040677, 0x0ea9b35e, 0x5961f14f, 0x67fda063,
+ 0xa48a5a31, 0xc6524e55, 0x283d325e, 0x3f37515f, 0x96b94b3e, 0xacce620e, 0x6481cc5b, 0xa4a06d4b,
+ 0x9e95d2d9, 0xe40c03d5, 0xc2f4514b, 0xb79aad44, 0xf64be843, 0xb2064070, 0xfca00455, 0x429dfa4e,
+ 0x2323f173, 0xeda4185e, 0xabd5227d, 0x9efd4d58, 0xb1104758, 0x4811e955, 0xbd9ab355, 0xe921f44b,
+ 0x9f166dce, 0x09e279b2, 0xe0c9ac7b, 0x7901a5ad, 0xa145d4b0, 0x79104671, 0xec31e35a, 0x4fe0b555,
+ 0xc7d9cbad, 0xad057f55, 0xe94cc759, 0x7fe0b043, 0xe4529f2e, 0x0d4dd4b2, 0x9f11a54d, 0x031e2e4e,
+ 0xe6014f5f, 0x11d1ca6c, 0x26bd7f61, 0xeb86854f, 0x4d347b57, 0x116bbe2e, 0xdba7234e, 0x7bcbfd2e,
+ 0x174dd4b2, 0x6686762e, 0xb089ba50, 0xc6258246, 0x087e767b, 0xc4a8cb4a, 0x595dba50, 0x7f0ae502,
+ 0x7b1dbd5a, 0xa0603492, 0x57d1af4b, 0x9e21ffd4, 0x6393064d, 0x7407376e, 0xe484762e, 0x122a4e53,
+ 0x4a37aa43, 0x3888a6be, 0xee77864e, 0x039c8dd5, 0x688d89af, 0x0e988f62, 0x08218246, 0xfc2f8246,
+ 0xd1d97040, 0xd64cd4b2, 0x5ae4a6b8, 0x7d0de9bc, 0x8d304d61, 0x06c5c672, 0xa4c8bd4d, 0xe0fd373b,
+ 0x575ebe4d, 0x72d26277, 0x55570f55, 0x77b154d9, 0xe214293a, 0xfc740f4b, 0xfe3f6a57, 0xa9c55f02,
+ 0xae4054db, 0x2394d918, 0xb511b24a, 0xb8741ab2, 0x0758e65e, 0xc7b5795b, 0xb0a30a4c, 0xaf7f170c,
+ 0xf3b4762e, 0x8179576d, 0x738a1581, 0x4b95b64c, 0x9829b618, 0x1bea932e, 0x7bdeaa4b, 0xcb5e0281,
+ 0x65618f54, 0x0658474b, 0x27066acf, 0x40556d65, 0x7d204d53, 0xf28bc244, 0xdce23455, 0xadc0ff54,
+ 0x3863c948, 0xcee34e5f, 0xdeb85e02, 0x2ed17a61, 0x6a7b094d, 0x7f0cfc40, 0x59603f54, 0x3220afbc,
+ 0xb5dfd962, 0x125d21c0, 0x13f8d243, 0xacfefb4e, 0x86c2c147, 0x3d8bbd59, 0xbd02a21f, 0x2593042e,
+ 0xc6a17a7c, 0x28925861, 0xb487ed44, 0xb5f4fd6d, 0x90c28a45, 0x5a14f74d, 0x43d71b4c, 0x728ebb5d,
+ 0x885bf950, 0x08134dd0, 0x38ec046e, 0xc575684b, 0x50082d2e, 0xa2f47757, 0x270f86ae, 0xf3ff6462,
+ 0x10ed3f4e, 0x4b58d462, 0xe01ce23e, 0x8c5b092e, 0x63e52f4e, 0x22c1e85d, 0xa908f54e, 0x8591624f,
+ 0x2c0fb94e, 0xa280ba3c, 0xb6f41b4c, 0x24f9aa47, 0x27201647, 0x3a3ea6dc, 0xa14fc3be, 0x3c34bdd5,
+ 0x5b8d4f5b, 0xaadeaf4b, 0xc71cab50, 0x15697a4c, 0x9a1a734c, 0x2a037d81, 0x2590bd59, 0x48ec2741,
+ 0x53489c5b, 0x7f00314b, 0x2170d362, 0xf2e92542, 0x42c10b44, 0x98f0f118, 0x883a3456, 0x099a932e,
+ 0xea38f7bc, 0x644e9247, 0xbb61b62e, 0x30e0863d, 0x5f51be54, 0x207215c7, 0x5f306c45, 0xaa7f3932,
+ 0x98da7d45, 0x4e339b59, 0x2e411581, 0xa808f618, 0xad2c0c59, 0x54476741, 0x09e99fd1, 0x5db8f752,
+ 0xc16df8bd, 0x1dd4b44f, 0x106edf2e, 0x9e15c180, 0x2ad6b56f, 0x633a5332, 0xff33787c, 0x077cb545,
+ 0x6610be6d, 0x75aad2c4, 0x72fb4d5b, 0xe81e0f59, 0x576f6332, 0x47333373, 0x351ed783, 0x2d90fb50,
+ 0x8d5e0f6c, 0x5b27a552, 0xdb293ebb, 0xe55ef950, 0x4b133ad8, 0x75df975a, 0x7b6a8740, 0xa899464b,
+ 0xfab15161, 0x10f8b64d, 0xd055ea4d, 0xee8e146b, 0x4b14afb8, 0x4bc1c44a, 0x9b961dcc, 0xd111ff43,
+ 0xfca0b745, 0xc800e412, 0x0afad9d1, 0xf751c350, 0xf9f0cccf, 0xa290a545, 0x8ef13763, 0x7ec70d59,
+ 0x2b066acf, 0x65496c45, 0xade02c1b, 0xae6eb077, 0x92c1e65b, 0xc064e6a9, 0xc649e56d, 0x5287a243,
+ 0x36de4f5b, 0x5b1df6ad, 0x65c39a59, 0xdba805b2, 0x20067aa8, 0x6457e56d, 0x3cee26cf, 0xfd3ff26d,
+ 0x04f86d4a, 0x06b8e048, 0xa93bcd5c, 0x91135852, 0xbe90a643, 0x8fa0094d, 0x06d8215f, 0x2677094d,
+ 0xd735685c, 0x164a00c9, 0x5209ac5f, 0xa9564c5c, 0x3b504f5f, 0xcc826bd0, 0x4615042e, 0x5fe13b4a,
+ 0x8c81b86d, 0x879ab68c, 0x1de564b8, 0x434487d8, 0x2dcb1b63, 0x82ab524a, 0xb0676abb, 0xa13d9c62,
+ 0xdbb5b86d, 0x5b7f4b59, 0xaddfb44d, 0xad773532, 0x3997054c, 0x72cebd89, 0xb194544c, 0xc5b8046e,
+ 0x6e1adeb2, 0xaa5abb51, 0xefb54b44, 0x15efc54f, 0xe9f1bc4d, 0x5f401b6c, 0x97f018ad, 0xc82f9252,
+ 0x2cdc762e, 0x8e52e56d, 0x1827175e, 0x9b7d7d80, 0xb2ad6845, 0x51065140, 0x71180a18, 0x5b27006c,
+ 0x0621e255, 0x721cbe58, 0x670c0cb8, 0xf8bd715d, 0xe0bdc5d9, 0xed843501, 0x4b84554d, 0x7f1a18bc,
+ 0x53bcaf47, 0x5729d35f, 0xf0dda246, 0x22382bd0, 0x4d641fb0, 0x316afcde, 0x50a22f1f, 0x73608046,
+ 0xc461d84a, 0xb2dbe247,
};
int64 nStart = GetTime();
loop
{
- // Limit outbound connections
vnThreadsRunning[1]--;
Sleep(500);
+ vnThreadsRunning[1]++;
+ if (fShutdown)
+ return;
+
+ // Limit outbound connections
loop
{
int nOutbound = 0;
nMaxOutboundConnections = min(nMaxOutboundConnections, (int)GetArg("-maxconnections", 125));
if (nOutbound < nMaxOutboundConnections)
break;
+ vnThreadsRunning[1]--;
Sleep(2000);
+ vnThreadsRunning[1]++;
if (fShutdown)
return;
}
- vnThreadsRunning[1]++;
- if (fShutdown)
- return;
+
+ bool fAddSeeds = false;
CRITICAL_BLOCK(cs_mapAddresses)
{
// Add seed nodes if IRC isn't working
bool fTOR = (fUseProxy && addrProxy.port == htons(9050));
- if (mapAddresses.empty() && (GetTime() - nStart > 60 || fTOR) && !fTestNet)
+ if (mapAddresses.empty() && (GetTime() - nStart > 60 || fUseProxy) && !fTestNet)
+ fAddSeeds = true;
+ }
+
+ if (fAddSeeds)
+ {
+ for (int i = 0; i < ARRAYLEN(pnSeed); i++)
{
- for (int i = 0; i < ARRAYLEN(pnSeed); i++)
- {
- // It'll only connect to one or two seed nodes because once it connects,
- // it'll get a pile of addresses with newer timestamps.
- // Seed nodes are given a random 'last seen time' of between one and two
- // weeks ago.
- const int64 nOneWeek = 7*24*60*60;
- CAddress addr;
- addr.ip = pnSeed[i];
- addr.nTime = GetTime()-GetRand(nOneWeek)-nOneWeek;
- AddAddress(addr);
- }
+ // It'll only connect to one or two seed nodes because once it connects,
+ // it'll get a pile of addresses with newer timestamps.
+ // Seed nodes are given a random 'last seen time' of between one and two
+ // weeks ago.
+ const int64 nOneWeek = 7*24*60*60;
+ CAddress addr;
+ addr.ip = pnSeed[i];
+ addr.nTime = GetTime()-GetRand(nOneWeek)-nOneWeek;
+ AddAddress(addr);
}
}
-
//
// Choose an address to connect to based on most recently seen
//
// Start threads
//
+ if (GetBoolArg("-nodnsseed"))
+ printf("DNS seeding disabled\n");
+ else
+ if (!CreateThread(ThreadDNSAddressSeed, NULL))
+ printf("Error: CreateThread(ThreadDNSAddressSeed) failed\n");
+
// Map ports with UPnP
if (fHaveUPnP)
MapPort(fUseUPnP);
fShutdown = true;
nTransactionsUpdated++;
int64 nStart = GetTime();
- while (vnThreadsRunning[0] > 0 || vnThreadsRunning[2] > 0 || vnThreadsRunning[3] > 0 || vnThreadsRunning[4] > 0
+ while (vnThreadsRunning[0] > 0 || vnThreadsRunning[1] > 0 || vnThreadsRunning[2] > 0 || vnThreadsRunning[3] > 0 || vnThreadsRunning[4] > 0
#ifdef USE_UPNP
|| vnThreadsRunning[5] > 0
#endif
if (vnThreadsRunning[3] > 0) printf("ThreadBitcoinMiner still running\n");
if (vnThreadsRunning[4] > 0) printf("ThreadRPCServer still running\n");
if (fHaveUPnP && vnThreadsRunning[5] > 0) printf("ThreadMapPort still running\n");
+ if (vnThreadsRunning[6] > 0) printf("ThreadDNSAddressSeed still running\n");
while (vnThreadsRunning[2] > 0 || vnThreadsRunning[4] > 0)
Sleep(20);
Sleep(50);
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2011 The Bitcoin developers
+// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_NET_H
void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1);
bool AnySubscribed(unsigned int nChannel);
void MapPort(bool fMapPort);
-void DNSAddressSeed();
bool BindListenPort(std::string& strError=REF(std::string()));
void StartNode(void* parg);
bool StopNode();
// Make sure not to reuse time indexes to keep things in the same order
int64 nNow = (GetTime() - 1) * 1000000;
static int64 nLastTime;
- nLastTime = nNow = std::max(nNow, ++nLastTime);
+ ++nLastTime;
+ nNow = std::max(nNow, nLastTime);
+ nLastTime = nNow;
// Each retry is 2 minutes after the last
nRequestTime = std::max(nRequestTime + 2 * 60 * 1000000, nNow);
void BeginMessage(const char* pszCommand)
{
- cs_vSend.Enter("cs_vSend", __FILE__, __LINE__);
+ ENTER_CRITICAL_SECTION(cs_vSend);
if (nHeaderStart != -1)
AbortMessage();
nHeaderStart = vSend.size();
vSend.resize(nHeaderStart);
nHeaderStart = -1;
nMessageStart = -1;
- cs_vSend.Leave();
+ LEAVE_CRITICAL_SECTION(cs_vSend);
if (fDebug)
printf("(aborted)\n");
nHeaderStart = -1;
nMessageStart = -1;
- cs_vSend.Leave();
+ LEAVE_CRITICAL_SECTION(cs_vSend);
}
void EndMessageAbortIfEmpty()
/// when NTP implemented, change to just nTime = GetAdjustedTime()
int64 nTime = (fInbound ? GetAdjustedTime() : GetTime());
CAddress addrYou = (fUseProxy ? CAddress("0.0.0.0") : addr);
- CAddress addrMe = (fUseProxy ? CAddress("0.0.0.0") : addrLocalHost);
+ CAddress addrMe = (fUseProxy || !addrLocalHost.IsRoutable() ? CAddress("0.0.0.0") : addrLocalHost);
RAND_bytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce));
PushMessage("version", VERSION, nLocalServices, nTime, addrYou, addrMe,
nLocalHostNonce, std::string(pszSubVer), nBestHeight);
#define wxHELP 0x00008000
#define wxMORE 0x00010000
#define wxSETUP 0x00020000
+// Force blocking, modal message box dialog (not just notification)
+#define wxMODAL 0x00040000
inline int MyMessageBox(const std::string& message, const std::string& caption="Message", int style=wxOK, wxWindow* parent=NULL, int x=-1, int y=-1)
{
--- /dev/null
+*
+!.gitignore
#include "addresstablemodel.h"
#include "editaddressdialog.h"
#include "csvmodelwriter.h"
+#include "guiutil.h"
#include <QSortFilterProxyModel>
#include <QClipboard>
-#include <QFileDialog>
#include <QMessageBox>
AddressBookPage::AddressBookPage(Mode mode, Tabs tab, QWidget *parent) :
void AddressBookPage::exportClicked()
{
// CSV is currently the only supported format
- QString filename = QFileDialog::getSaveFileName(
+ QString filename = GUIUtil::getSaveFileName(
this,
- tr("Export Address Book Data"),
- QDir::currentPath(),
+ tr("Export Address Book Data"), QString(),
tr("Comma separated file (*.csv)"));
if (filename.isNull()) return;
ui->warningLabel->setText(tr("Enter the old and new passphrase to the wallet."));
break;
}
- resize(minimumSize()); // Get rid of extra space in dialog
textChanged();
connect(ui->passEdit1, SIGNAL(textChanged(QString)), this, SLOT(textChanged()));
void AskPassphraseDialog::accept()
{
- std::string oldpass, newpass1, newpass2;
+ SecureString oldpass, newpass1, newpass2;
if(!model)
return;
- // TODO: mlock memory / munlock on return so they will not be swapped out, really need "mlockedstring" wrapper class to do this safely
oldpass.reserve(MAX_PASSPHRASE_SIZE);
newpass1.reserve(MAX_PASSPHRASE_SIZE);
newpass2.reserve(MAX_PASSPHRASE_SIZE);
- oldpass.assign(ui->passEdit1->text().toStdString());
- newpass1.assign(ui->passEdit2->text().toStdString());
- newpass2.assign(ui->passEdit3->text().toStdString());
+ // TODO: get rid of this .c_str() by implementing SecureString::operator=(std::string)
+ // Alternately, find a way to make this input mlock()'d to begin with.
+ oldpass.assign(ui->passEdit1->text().toStdString().c_str());
+ newpass1.assign(ui->passEdit2->text().toStdString().c_str());
+ newpass2.assign(ui->passEdit3->text().toStdString().c_str());
switch(mode)
{
int ThreadSafeMessageBox(const std::string& message, const std::string& caption, int style, wxWindow* parent, int x, int y)
{
+ bool modal = style & wxMODAL;
+
+ if (modal)
+ while (!guiref)
+ sleep(1);
+
// Message from network thread
if(guiref)
{
QMetaObject::invokeMethod(guiref, "error", Qt::QueuedConnection,
Q_ARG(QString, QString::fromStdString(caption)),
- Q_ARG(QString, QString::fromStdString(message)));
+ Q_ARG(QString, QString::fromStdString(message)),
+ Q_ARG(bool, modal));
}
else
{
void MainFrameRepaint()
{
+ if(guiref)
+ QMetaObject::invokeMethod(guiref, "refreshStatusBar", Qt::QueuedConnection);
}
void InitMessage(const std::string &message)
app.setApplicationName(QApplication::translate("main", "Bitcoin-Qt"));
QSplashScreen splash(QPixmap(":/images/splash"), 0);
- splash.show();
- splash.setAutoFillBackground(true);
- splashref = &splash;
+ if (!GetBoolArg("-min"))
+ {
+ splash.show();
+ splash.setAutoFillBackground(true);
+ splashref = &splash;
+ }
app.processEvents();
// Put this in a block, so that BitcoinGUI is cleaned up properly before
// calling Shutdown().
BitcoinGUI window;
- splash.finish(&window);
+ if (splashref)
+ splash.finish(&window);
OptionsModel optionsModel(pwalletMain);
ClientModel clientModel(&optionsModel);
WalletModel walletModel(pwalletMain, &optionsModel);
* Qt4 bitcoin GUI.
*
* W.J. van der Laan 2011
+ * The Bitcoin Developers 2011
*/
#include "bitcoingui.h"
#include "transactiontablemodel.h"
#include <QStackedWidget>
#include <QDateTime>
#include <QMovie>
+#include <QTimer>
#include <QDragEnterEvent>
#include <QUrl>
walletModel(0),
encryptWalletAction(0),
changePassphraseAction(0),
+ aboutQtAction(0),
trayIcon(0),
notificator(0)
{
sendCoinsAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_2));
tabGroup->addAction(sendCoinsAction);
+ connect(overviewAction, SIGNAL(triggered()), this, SLOT(showNormal()));
connect(overviewAction, SIGNAL(triggered()), this, SLOT(gotoOverviewPage()));
+ connect(historyAction, SIGNAL(triggered()), this, SLOT(showNormal()));
connect(historyAction, SIGNAL(triggered()), this, SLOT(gotoHistoryPage()));
+ connect(addressBookAction, SIGNAL(triggered()), this, SLOT(showNormal()));
connect(addressBookAction, SIGNAL(triggered()), this, SLOT(gotoAddressBookPage()));
+ connect(receiveCoinsAction, SIGNAL(triggered()), this, SLOT(showNormal()));
connect(receiveCoinsAction, SIGNAL(triggered()), this, SLOT(gotoReceiveCoinsPage()));
+ connect(sendCoinsAction, SIGNAL(triggered()), this, SLOT(showNormal()));
connect(sendCoinsAction, SIGNAL(triggered()), this, SLOT(gotoSendCoinsPage()));
quitAction = new QAction(QIcon(":/icons/quit"), tr("E&xit"), this);
quitAction->setMenuRole(QAction::QuitRole);
aboutAction = new QAction(QIcon(":/icons/bitcoin"), tr("&About %1").arg(qApp->applicationName()), this);
aboutAction->setToolTip(tr("Show information about Bitcoin"));
- aboutAction->setMenuRole(QAction::AboutQtRole);
+ aboutAction->setMenuRole(QAction::AboutRole);
+ aboutQtAction = new QAction(tr("About &Qt"), this);
+ aboutQtAction->setToolTip(tr("Show information about Qt"));
+ aboutQtAction->setMenuRole(QAction::AboutQtRole);
optionsAction = new QAction(QIcon(":/icons/options"), tr("&Options..."), this);
optionsAction->setToolTip(tr("Modify configuration options for bitcoin"));
optionsAction->setMenuRole(QAction::PreferencesRole);
connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
connect(optionsAction, SIGNAL(triggered()), this, SLOT(optionsClicked()));
connect(aboutAction, SIGNAL(triggered()), this, SLOT(aboutClicked()));
+ connect(aboutQtAction, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
connect(openBitcoinAction, SIGNAL(triggered()), this, SLOT(showNormal()));
connect(encryptWalletAction, SIGNAL(triggered(bool)), this, SLOT(encryptWallet(bool)));
connect(changePassphraseAction, SIGNAL(triggered()), this, SLOT(changePassphrase()));
QMenu *help = appMenuBar->addMenu(tr("&Help"));
help->addAction(aboutAction);
+ help->addAction(aboutQtAction);
}
void BitcoinGUI::createToolBars()
// Click on system tray icon triggers "open bitcoin"
openBitcoinAction->trigger();
}
-
}
#endif
{
if(!clientModel)
return;
- int initTotal = clientModel->getNumBlocksAtStartup();
int total = clientModel->getNumBlocksOfPeers();
QString tooltip;
if(count < total)
{
- progressBarLabel->setVisible(true);
- progressBar->setVisible(true);
- progressBar->setMaximum(total - initTotal);
- progressBar->setValue(count - initTotal);
+ if (clientModel->getStatusBarWarnings() == "")
+ {
+ progressBarLabel->setVisible(true);
+ progressBarLabel->setText(tr("Synchronizing with network..."));
+ progressBar->setVisible(true);
+ progressBar->setMaximum(total);
+ progressBar->setValue(count);
+ }
+ else
+ {
+ progressBarLabel->setText(clientModel->getStatusBarWarnings());
+ progressBarLabel->setVisible(true);
+ progressBar->setVisible(false);
+ }
tooltip = tr("Downloaded %1 of %2 blocks of transaction history.").arg(count).arg(total);
}
else
{
- progressBarLabel->setVisible(false);
+ if (clientModel->getStatusBarWarnings() == "")
+ progressBarLabel->setVisible(false);
+ else
+ {
+ progressBarLabel->setText(clientModel->getStatusBarWarnings());
+ progressBarLabel->setVisible(true);
+ }
progressBar->setVisible(false);
tooltip = tr("Downloaded %1 blocks of transaction history.").arg(count);
}
QString text;
// Represent time from last generated block in human readable text
- if(secs < 60)
+ if(secs <= 0)
+ {
+ // Fully up to date. Leave text empty.
+ }
+ else if(secs < 60)
{
text = tr("%n second(s) ago","",secs);
}
}
// Set icon state: spinning if catching up, tick otherwise
- if(secs < 30*60)
+ if(secs < 90*60)
{
- tooltip = tr("Up to date") + QString("\n") + tooltip;
+ tooltip = tr("Up to date") + QString(".\n") + tooltip;
labelBlocksIcon->setPixmap(QIcon(":/icons/synced").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE));
}
else
syncIconMovie->start();
}
- tooltip += QString("\n");
- tooltip += tr("Last received block was generated %1.").arg(text);
+ if(!text.isEmpty())
+ {
+ tooltip += QString("\n");
+ tooltip += tr("Last received block was generated %1.").arg(text);
+ }
labelBlocksIcon->setToolTip(tooltip);
progressBarLabel->setToolTip(tooltip);
progressBar->setToolTip(tooltip);
}
-void BitcoinGUI::error(const QString &title, const QString &message)
+void BitcoinGUI::refreshStatusBar()
+{
+ /* Might display multiple times in the case of multiple alerts
+ static QString prevStatusBar;
+ QString newStatusBar = clientModel->getStatusBarWarnings();
+ if (prevStatusBar != newStatusBar)
+ {
+ prevStatusBar = newStatusBar;
+ error(tr("Network Alert"), newStatusBar);
+ }*/
+ setNumBlocks(clientModel->getNumBlocks());
+}
+
+void BitcoinGUI::error(const QString &title, const QString &message, bool modal)
{
// Report errors from network/worker thread
- notificator->notify(Notificator::Critical, title, message);
+ if (modal)
+ {
+ QMessageBox::critical(this, title, message, QMessageBox::Ok, QMessageBox::Ok);
+ } else {
+ notificator->notify(Notificator::Critical, title, message);
+ }
}
void BitcoinGUI::changeEvent(QEvent *e)
{
+ QMainWindow::changeEvent(e);
#ifndef Q_WS_MAC // Ignored on Mac
if(e->type() == QEvent::WindowStateChange)
{
if(clientModel && clientModel->getOptionsModel()->getMinimizeToTray())
{
- if(isMinimized())
+ QWindowStateChangeEvent *wsevt = static_cast<QWindowStateChangeEvent*>(e);
+ if(!(wsevt->oldState() & Qt::WindowMinimized) && isMinimized())
{
- hide();
+ QTimer::singleShot(0, this, SLOT(hide()));
e->ignore();
}
- else
- {
- show();
- e->accept();
- }
}
}
#endif
- QMainWindow::changeEvent(e);
}
void BitcoinGUI::closeEvent(QCloseEvent *event)
void BitcoinGUI::gotoOverviewPage()
{
- show();
overviewAction->setChecked(true);
centralWidget->setCurrentWidget(overviewPage);
void BitcoinGUI::gotoHistoryPage()
{
- show();
historyAction->setChecked(true);
centralWidget->setCurrentWidget(transactionsPage);
void BitcoinGUI::gotoAddressBookPage()
{
- show();
addressBookAction->setChecked(true);
centralWidget->setCurrentWidget(addressBookPage);
void BitcoinGUI::gotoReceiveCoinsPage()
{
- show();
receiveCoinsAction->setChecked(true);
centralWidget->setCurrentWidget(receiveCoinsPage);
void BitcoinGUI::gotoSendCoinsPage()
{
- show();
sendCoinsAction->setChecked(true);
centralWidget->setCurrentWidget(sendCoinsPage);
QAction *exportAction;
QAction *encryptWalletAction;
QAction *changePassphraseAction;
+ QAction *aboutQtAction;
QSystemTrayIcon *trayIcon;
Notificator *notificator;
void setNumConnections(int count);
void setNumBlocks(int count);
void setEncryptionStatus(int status);
+ /** Set the status bar text if there are any warnings (removes sync progress bar if applicable) */
+ void refreshStatusBar();
- void error(const QString &title, const QString &message);
+ void error(const QString &title, const QString &message, bool modal = false);
/* It is currently not possible to pass a return value to another thread through
BlockingQueuedConnection, so use an indirected pointer.
http://bugreports.qt.nokia.com/browse/QTBUG-10440
"86400)\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Don't attempt to use UPnP to map the listening port\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Attempt to use UPnP to map the listening port\n"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Fee per KB to add to transactions you send\n"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Fee per kB to add to transactions you send\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Accept command line and JSON-RPC commands\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Run in the background as a daemon and accept commands\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Use the test network\n"),
return GetNumBlocksOfPeers();
}
+QString ClientModel::getStatusBarWarnings() const
+{
+ return QString::fromStdString(GetWarnings("statusbar"));
+}
+
OptionsModel *ClientModel::getOptionsModel()
{
return optionsModel;
bool inInitialBlockDownload() const;
// Return conservative estimate of total number of blocks, or 0 if unknown
int getNumBlocksOfPeers() const;
+ //! Return warnings to be displayed in status bar
+ QString getStatusBarWarnings() const;
QString formatFullVersion() const;
<item>
<widget class="QLabel" name="label_2">
<property name="text">
- <string>Copyright © 2009-2011 Bitcoin Developers
+ <string>Copyright © 2009-2012 Bitcoin Developers
This is experimental software.
<rect>
<x>0</x>
<y>0</y>
- <width>589</width>
- <height>228</height>
+ <width>598</width>
+ <height>187</height>
</rect>
</property>
<property name="sizePolicy">
<property name="textFormat">
<enum>Qt::RichText</enum>
</property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
</widget>
</item>
<item>
</layout>
</item>
<item>
- <spacer name="verticalSpacer">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>40</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
<verstretch>0</verstretch>
</sizepolicy>
</property>
+ <property name="toolTip">
+ <string>Remove all transaction fields</string>
+ </property>
<property name="text">
<string>Clear all</string>
</property>
<item>
<widget class="QToolButton" name="addressBookButton">
<property name="toolTip">
- <string>Choose adress from address book</string>
+ <string>Choose address from address book</string>
</property>
<property name="text">
<string/>
<property name="toolTip">
<string>This pane shows a detailed description of the transaction</string>
</property>
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
</widget>
</item>
<item>
#include <QFont>
#include <QLineEdit>
#include <QUrl>
+#include <QFileDialog>
+#include <QDesktopServices>
QString GUIUtil::dateTimeStr(qint64 nTime)
{
}
return true;
}
+
+bool GUIUtil::parseBitcoinURL(QString url, SendCoinsRecipient *out)
+{
+ // Convert bitcoin:// to bitcoin:
+ //
+ // Cannot handle this later, because bitcoin:// will cause Qt to see the part after // as host,
+ // which will lowercase it (and thus invalidate the address).
+ if(url.startsWith("bitcoin://"))
+ {
+ url.replace(0, 10, "bitcoin:");
+ }
+ QUrl urlInstance(url);
+ return parseBitcoinURL(&urlInstance, out);
+}
+
+QString GUIUtil::getSaveFileName(QWidget *parent, const QString &caption,
+ const QString &dir,
+ const QString &filter,
+ QString *selectedSuffixOut)
+{
+ QString selectedFilter;
+ QString myDir;
+ if(dir.isEmpty()) // Default to user documents location
+ {
+ myDir = QDesktopServices::storageLocation(QDesktopServices::DocumentsLocation);
+ }
+ else
+ {
+ myDir = dir;
+ }
+ QString result = QFileDialog::getSaveFileName(parent, caption, myDir, filter, &selectedFilter);
+
+ /* Extract first suffix from filter pattern "Description (*.foo)" or "Description (*.foo *.bar ...) */
+ QRegExp filter_re(".* \\(\\*\\.(.*)[ \\)]");
+ QString selectedSuffix;
+ if(filter_re.exactMatch(selectedFilter))
+ {
+ selectedSuffix = filter_re.cap(1);
+ }
+
+ /* Add suffix if needed */
+ QFileInfo info(result);
+ if(!result.isEmpty())
+ {
+ if(info.suffix().isEmpty() && !selectedSuffix.isEmpty())
+ {
+ /* No suffix specified, add selected suffix */
+ if(!result.endsWith("."))
+ result.append(".");
+ result.append(selectedSuffix);
+ }
+ }
+
+ /* Return selected suffix if asked to */
+ if(selectedSuffixOut)
+ {
+ *selectedSuffixOut = selectedSuffix;
+ }
+ return result;
+}
+
// Parse "bitcoin:" URL into recipient object, return true on succesful parsing
// See Bitcoin URL definition discussion here: https://bitcointalk.org/index.php?topic=33490.0
static bool parseBitcoinURL(const QUrl *url, SendCoinsRecipient *out);
+ static bool parseBitcoinURL(QString url, SendCoinsRecipient *out);
+
+ /** Get save file name, mimics QFileDialog::getSaveFileName, except that it appends a default suffix
+ when no suffix is provided by the user.
+
+ @param[in] parent Parent window (or 0)
+ @param[in] caption Window caption (or empty, for default)
+ @param[in] dir Starting directory (or empty, to default to documents directory)
+ @param[in] filter Filter specification such as "Comma Separated Files (*.csv)"
+ @param[out] selectedSuffixOut Pointer to return the suffix (file type) that was selected (or 0).
+ Can be useful when choosing the save file format based on suffix.
+ */
+ static QString getSaveFileName(QWidget *parent=0, const QString &caption=QString(),
+ const QString &dir=QString(), const QString &filter=QString(),
+ QString *selectedSuffixOut=0);
+
};
#endif // GUIUTIL_H
</message>
<message>
<location filename="../optionsdialog.cpp" line="217"/>
- <source>Optional transaction fee per KB that helps make sure your transactions are processed quickly. Most transactions are 1KB. Fee 0.01 recommended.</source>
- <translation>Valgfri transaktionsgebyr pr. KB, der hjælper dine transaktioner med at blive behandlet hurtigt. De fleste transaktioner er på 1KB. Gebyr på 0.01 anbefales.</translation>
+ <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1kB. Fee 0.01 recommended.</source>
+ <translation>Valgfri transaktionsgebyr pr. kB, der hjælper dine transaktioner med at blive behandlet hurtigt. De fleste transaktioner er på 1kB. Gebyr på 0.01 anbefales.</translation>
</message>
<message>
<location filename="../optionsdialog.cpp" line="223"/>
</message>
<message>
<location filename="../optionsdialog.cpp" line="226"/>
- <source>Optional transaction fee per KB that helps make sure your transactions are processed quickly. Most transactions are 1KB. Fee 0.01 recommended.</source>
- <translation>Valgfri transaktionsgebyr pr. KB, der hjælper dine transaktioner med at blive behandlet hurtigt. De fleste transaktioner er på 1KB. Gebyr på 0.01 anbefales.</translation>
+ <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1kB. Fee 0.01 recommended.</source>
+ <translation>Valgfri transaktionsgebyr pr. kB, der hjælper dine transaktioner med at blive behandlet hurtigt. De fleste transaktioner er på 1kB. Gebyr på 0.01 anbefales.</translation>
</message>
</context>
<context>
</message>
<message>
<location filename="../forms/sendcoinsentry.ui" line="103"/>
- <source>Choose adress from address book</source>
+ <source>Choose address from address book</source>
<translation>Vælg adresse fra adressebog</translation>
</message>
<message>
</message>
<message>
<location filename="../bitcoinstrings.cpp" line="23"/>
- <source>Fee per KB to add to transactions you send
+ <source>Fee per kB to add to transactions you send
</source>
- <translation>Gebyr pr. KB, som skal tilføjes til transaktioner du sender
+ <translation>Gebyr pr. kB, som skal tilføjes til transaktioner du sender
</translation>
</message>
<message>
<message>
<location filename="../bitcoingui.cpp" line="204"/>
<source>&About %1</source>
- <translation type="unfinished"/>
+ <translation>&Über %1</translation>
</message>
<message>
<location filename="../bitcoingui.cpp" line="205"/>
</message>
<message>
<location filename="../optionsdialog.cpp" line="217"/>
- <source>Optional transaction fee per KB that helps make sure your transactions are processed quickly. Most transactions are 1KB. Fee 0.01 recommended.</source>
- <translation>Zusätzliche Transaktionsgebühr pro KB, welche sicherstellt, dass Ihre Transaktionen schnell bearbeitet werden. Die meisten Transaktionen sind 1 KB groß. Eine Gebühr von 0.01 wird empfohlen.</translation>
+ <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1kB. Fee 0.01 recommended.</source>
+ <translation>Zusätzliche Transaktionsgebühr pro kB, welche sicherstellt, dass Ihre Transaktionen schnell bearbeitet werden. Die meisten Transaktionen sind 1 kB groß. Eine Gebühr von 0.01 wird empfohlen.</translation>
</message>
<message>
<location filename="../optionsdialog.cpp" line="223"/>
</message>
<message>
<location filename="../optionsdialog.cpp" line="226"/>
- <source>Optional transaction fee per KB that helps make sure your transactions are processed quickly. Most transactions are 1KB. Fee 0.01 recommended.</source>
- <translation>Zusätzliche Transaktionsgebühr pro KB, welche sicherstellt, dass Ihre Transaktionen schnell bearbeitet werden. Die meisten Transaktionen sind 1 KB groß. Eine Gebühr von 0.01 wird empfohlen.</translation>
+ <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1kB. Fee 0.01 recommended.</source>
+ <translation>Zusätzliche Transaktionsgebühr pro kB, welche sicherstellt, dass Ihre Transaktionen schnell bearbeitet werden. Die meisten Transaktionen sind 1 kB groß. Eine Gebühr von 0.01 wird empfohlen.</translation>
</message>
</context>
<context>
</message>
<message>
<location filename="../forms/sendcoinsentry.ui" line="103"/>
- <source>Choose adress from address book</source>
+ <source>Choose address from address book</source>
<translation>Adresse aus dem Adressbuch auswählen</translation>
</message>
<message>
</message>
<message>
<location filename="../bitcoinstrings.cpp" line="23"/>
- <source>Fee per KB to add to transactions you send
+ <source>Fee per kB to add to transactions you send
</source>
- <translation>Gebühr pro KB, die gesendeten Transaktionen hinzugefügt wird
+ <translation>Gebühr pro kB, die gesendeten Transaktionen hinzugefügt wird
</translation>
</message>
<message>
<message>
<location filename="../bitcoinstrings.cpp" line="111"/>
<source>Wallet encryption failed.</source>
- <translation type="unfinished"/>
+ <translation>Verschlüsselung der Brieftasche fehlgeschlagen.</translation>
</message>
<message>
<location filename="../bitcoinstrings.cpp" line="112"/>
<message>
<location filename="../bitcoinstrings.cpp" line="116"/>
<source>Wallet is unencrypted, please encrypt it first.</source>
- <translation type="unfinished"/>
+ <translation>Brieftasche nicht verschlüsselt, bitte zuerst verschlüsseln.</translation>
</message>
<message>
<location filename="../bitcoinstrings.cpp" line="117"/>
<source>Enter the new passphrase for the wallet.</source>
- <translation type="unfinished"/>
+ <translation>Gib eine neue Passphrase für die Brieftasche eine.</translation>
</message>
<message>
<location filename="../bitcoinstrings.cpp" line="118"/>
<source>Re-enter the new passphrase for the wallet.</source>
- <translation type="unfinished"/>
+ <translation>Gib die neue Passphrase erneut ein.</translation>
</message>
<message>
<location filename="../bitcoinstrings.cpp" line="119"/>
<source>Wallet Passphrase Changed.</source>
- <translation type="unfinished"/>
+ <translation>Passphrase geändert.</translation>
</message>
<message>
<location filename="../bitcoinstrings.cpp" line="120"/>
<message>
<location filename="../bitcoinstrings.cpp" line="129"/>
<source><b>Date:</b> </source>
- <translation type="unfinished"/>
+ <translation><b>Datum:</b></translation>
</message>
<message>
<location filename="../bitcoinstrings.cpp" line="130"/>
<message>
<location filename="../bitcoinstrings.cpp" line="131"/>
<source><b>From:</b> </source>
- <translation type="unfinished"/>
+ <translation><b>Von:</b></translation>
</message>
<message>
<location filename="../bitcoinstrings.cpp" line="132"/>
<message>
<location filename="../bitcoinstrings.cpp" line="140"/>
<source><b>Transaction fee:</b> </source>
- <translation type="unfinished"/>
+ <translation><b>Transaktionsgebühr:</b></translation>
</message>
<message>
<location filename="../bitcoinstrings.cpp" line="141"/>
<message>
<location filename="../bitcoinstrings.cpp" line="154"/>
<source>version %s</source>
- <translation type="unfinished"/>
+ <translation>Version %s</translation>
</message>
<message>
<location filename="../bitcoinstrings.cpp" line="155"/>
<message>
<location filename="../bitcoinstrings.cpp" line="157"/>
<source>Amount exceeds your balance </source>
- <translation type="unfinished"/>
+ <translation>Betrag übersteigt Ihr Guthaben </translation>
</message>
<message>
<location filename="../bitcoinstrings.cpp" line="158"/>
<message>
<location filename="../bitcoinstrings.cpp" line="160"/>
<source>Payment sent </source>
- <translation type="unfinished"/>
+ <translation>Zahlung gesendet</translation>
</message>
<message>
<location filename="../bitcoinstrings.cpp" line="161"/>
<message>
<location filename="../bitcoinstrings.cpp" line="162"/>
<source>Invalid address </source>
- <translation type="unfinished"/>
+ <translation>ungültige Adresse</translation>
</message>
<message>
<location filename="../bitcoinstrings.cpp" line="163"/>
<source>Sending %s to %s</source>
- <translation type="unfinished"/>
+ <translation>Sende %s an %s</translation>
</message>
<message>
<location filename="../bitcoinstrings.cpp" line="164"/>
<source>CANCELLED</source>
- <translation type="unfinished"/>
+ <translation>ABGEBROCHEN</translation>
</message>
<message>
<location filename="../bitcoinstrings.cpp" line="165"/>
<source>Cancelled</source>
- <translation type="unfinished"/>
+ <translation>Abgebrochen</translation>
</message>
<message>
<location filename="../bitcoinstrings.cpp" line="166"/>
<message>
<location filename="../bitcoinstrings.cpp" line="167"/>
<source>Error: </source>
- <translation type="unfinished"/>
+ <translation>Fehler: </translation>
</message>
<message>
<location filename="../bitcoinstrings.cpp" line="168"/>
<message>
<location filename="../bitcoinstrings.cpp" line="169"/>
<source>Connecting...</source>
- <translation type="unfinished"/>
+ <translation>Verbinde...</translation>
</message>
<message>
<location filename="../bitcoinstrings.cpp" line="170"/>
<source>Unable to connect</source>
- <translation type="unfinished"/>
+ <translation>Kann nicht verbinden</translation>
</message>
<message>
<location filename="../bitcoinstrings.cpp" line="171"/>
<message>
<location filename="../bitcoinstrings.cpp" line="181"/>
<source>Transaction aborted</source>
- <translation type="unfinished"/>
+ <translation>Transaktion abgebrochen</translation>
</message>
<message>
<location filename="../bitcoinstrings.cpp" line="182"/>
<message>
<location filename="../bitcoinstrings.cpp" line="183"/>
<source>Sending payment...</source>
- <translation type="unfinished"/>
+ <translation>Sende Zahlung...</translation>
</message>
<message>
<location filename="../bitcoinstrings.cpp" line="184"/>
<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 type="unfinished"/>
+ <translation>Fehler: Die Transaktion wurde abgelehnt. Dies kann passieren, wenn einige Ihrer Bitcoins aus Ihrer Brieftasche bereits ausgegeben wurden (z.B. aus einer Sicherungskopie Ihrer wallet.dat).</translation>
</message>
<message>
<location filename="../bitcoinstrings.cpp" line="188"/>
<source>Waiting for confirmation...</source>
- <translation type="unfinished"/>
+ <translation>Warte auf Bestätigung...</translation>
</message>
<message>
<location filename="../bitcoinstrings.cpp" line="189"/>
<message>
<location filename="../bitcoinstrings.cpp" line="194"/>
<source>Payment completed</source>
- <translation type="unfinished"/>
+ <translation>Die Zahlung wurde abgeschlossen</translation>
</message>
<message>
<location filename="../bitcoinstrings.cpp" line="195"/>
<source>Name</source>
- <translation type="unfinished"/>
+ <translation>Name</translation>
</message>
<message>
<location filename="../bitcoinstrings.cpp" line="196"/>
<message>
<location filename="../bitcoinstrings.cpp" line="198"/>
<source>Bitcoin Address</source>
- <translation type="unfinished"/>
+ <translation>Bitcoin Adresse</translation>
</message>
<message>
<location filename="../bitcoinstrings.cpp" line="199"/>
<message>
<location filename="../bitcoinstrings.cpp" line="204"/>
<source>Add Address</source>
- <translation type="unfinished"/>
+ <translation>Adresse hinzufügen</translation>
</message>
<message>
<location filename="../bitcoinstrings.cpp" line="205"/>
<source>Bitcoin</source>
- <translation type="unfinished"/>
+ <translation>Bitcoin</translation>
</message>
<message>
<location filename="../bitcoinstrings.cpp" line="206"/>
<source>Bitcoin - Generating</source>
- <translation type="unfinished"/>
+ <translation>Bitcoin - Generiere</translation>
</message>
<message>
<location filename="../bitcoinstrings.cpp" line="207"/>
<source>Bitcoin - (not connected)</source>
- <translation type="unfinished"/>
+ <translation>Bitcoin - (nicht verbunden)</translation>
</message>
<message>
<location filename="../bitcoinstrings.cpp" line="208"/>
<message>
<location filename="../bitcoinstrings.cpp" line="216"/>
<source>beta</source>
- <translation type="unfinished"/>
+ <translation>Beta</translation>
</message>
</context>
<context>
<message>
<location filename="../bitcoin.cpp" line="145"/>
<source>Bitcoin Qt</source>
- <translation type="unfinished"/>
+ <translation>Bitcoin Qt</translation>
</message>
</context>
</TS>
\ No newline at end of file
</message>
<message>
<location filename="../optionsdialog.cpp" line="217"/>
- <source>Optional transaction fee per KB that helps make sure your transactions are processed quickly. Most transactions are 1KB. Fee 0.01 recommended.</source>
+ <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1kB. Fee 0.01 recommended.</source>
<translation type="unfinished"></translation>
</message>
<message>
</message>
<message>
<location filename="../optionsdialog.cpp" line="226"/>
- <source>Optional transaction fee per KB that helps make sure your transactions are processed quickly. Most transactions are 1KB. Fee 0.01 recommended.</source>
+ <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1kB. Fee 0.01 recommended.</source>
<translation type="unfinished"></translation>
</message>
</context>
</message>
<message>
<location filename="../forms/sendcoinsentry.ui" line="103"/>
- <source>Choose adress from address book</source>
+ <source>Choose address from address book</source>
<translation type="unfinished"></translation>
</message>
<message>
</message>
<message>
<location filename="../bitcoinstrings.cpp" line="23"/>
- <source>Fee per KB to add to transactions you send
+ <source>Fee per kB to add to transactions you send
</source>
<translation type="unfinished"></translation>
</message>
-<?xml version="1.0" ?><!DOCTYPE TS><TS language="es" version="2.0">
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="es">
<defaultcodec>UTF-8</defaultcodec>
<context>
<name>AboutDialog</name>
<message>
<location filename="../bitcoingui.cpp" line="200"/>
<source>E&xit</source>
- <translation type="unfinished"/>
+ <translation>&Salir</translation>
</message>
<message>
<location filename="../bitcoingui.cpp" line="201"/>
<message>
<location filename="../bitcoingui.cpp" line="204"/>
<source>&About %1</source>
- <translation type="unfinished"/>
+ <translation>S&obre %1</translation>
</message>
<message>
<location filename="../bitcoingui.cpp" line="205"/>
<message numerus="yes">
<location filename="../bitcoingui.cpp" line="396"/>
<source>%n active connection(s) to Bitcoin network</source>
- <translation><numerusform>%n conexión activa hacia la red Bitcoin</numerusform><numerusform>%n conexiones activas hacia la red Bitcoin</numerusform></translation>
+ <translation>
+ <numerusform>%n conexión activa hacia la red Bitcoin</numerusform>
+ <numerusform>%n conexiones activas hacia la red Bitcoin</numerusform>
+ </translation>
</message>
<message>
<location filename="../bitcoingui.cpp" line="411"/>
<message numerus="yes">
<location filename="../bitcoingui.cpp" line="428"/>
<source>%n second(s) ago</source>
- <translation><numerusform>Hace %n segundo</numerusform><numerusform>Hace %n segundos</numerusform></translation>
+ <translation>
+ <numerusform>Hace %n segundo</numerusform>
+ <numerusform>Hace %n segundos</numerusform>
+ </translation>
</message>
<message numerus="yes">
<location filename="../bitcoingui.cpp" line="432"/>
<source>%n minute(s) ago</source>
- <translation><numerusform>Hace %n minuto</numerusform><numerusform>Hace %n minutos</numerusform></translation>
+ <translation>
+ <numerusform>Hace %n minuto</numerusform>
+ <numerusform>Hace %n minutos</numerusform>
+ </translation>
</message>
<message numerus="yes">
<location filename="../bitcoingui.cpp" line="436"/>
<source>%n hour(s) ago</source>
- <translation><numerusform>Hace %n hora</numerusform><numerusform>Hace %n horas</numerusform></translation>
+ <translation>
+ <numerusform>Hace %n hora</numerusform>
+ <numerusform>Hace %n horas</numerusform>
+ </translation>
</message>
<message numerus="yes">
<location filename="../bitcoingui.cpp" line="440"/>
<source>%n day(s) ago</source>
- <translation><numerusform>Hace %n día</numerusform><numerusform>Hace %n días</numerusform></translation>
+ <translation>
+ <numerusform>Hace %n día</numerusform>
+ <numerusform>Hace %n días</numerusform>
+ </translation>
</message>
<message>
<location filename="../bitcoingui.cpp" line="446"/>
</message>
<message>
<location filename="../optionsdialog.cpp" line="217"/>
- <source>Optional transaction fee per KB that helps make sure your transactions are processed quickly. Most transactions are 1KB. Fee 0.01 recommended.</source>
- <translation>Comisión opcional a las transacciones por KB que ayuda a asegurar que tus transacciones son procesadas rápidamente. La mayoría de las transacciones son de 1KB. Se recomienda una comisión de 0.01.</translation>
+ <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1kB. Fee 0.01 recommended.</source>
+ <translation>Comisión opcional a las transacciones por kB que ayuda a asegurar que tus transacciones son procesadas rápidamente. La mayoría de las transacciones son de 1kB. Se recomienda una comisión de 0.01.</translation>
</message>
<message>
<location filename="../optionsdialog.cpp" line="223"/>
</message>
<message>
<location filename="../optionsdialog.cpp" line="226"/>
- <source>Optional transaction fee per KB that helps make sure your transactions are processed quickly. Most transactions are 1KB. Fee 0.01 recommended.</source>
- <translation>Comisión opcional a las transacciones por KB que ayuda a asegurar que tus transacciones son procesadas rápidamente. La mayoría de las transacciones son de 1KB. Se recomienda una comisión de 0.01.</translation>
+ <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1kB. Fee 0.01 recommended.</source>
+ <translation>Comisión opcional a las transacciones por kB que ayuda a asegurar que tus transacciones son procesadas rápidamente. La mayoría de las transacciones son de 1kB. Se recomienda una comisión de 0.01.</translation>
</message>
</context>
<context>
<source><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
p, li { white-space: pre-wrap; }
-</style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;">
+</style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;">
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Wallet</span></p></body></html></source>
<translation><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
p, li { white-space: pre-wrap; }
-</style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;">
+</style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;">
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Cartera</span></p></body></html></translation>
</message>
<message>
</message>
<message>
<location filename="../forms/sendcoinsentry.ui" line="103"/>
- <source>Choose adress from address book</source>
+ <source>Choose address from address book</source>
<translation>Elije dirección de la guia</translation>
</message>
<message>
<message>
<location filename="../transactiondesc.cpp" line="70"/>
<source>, broadcast through %1 node</source>
- <translation>, emitido mediante %d nodo</translation>
+ <translation>, emitido mediante %1 nodo</translation>
</message>
<message>
<location filename="../transactiondesc.cpp" line="72"/>
<source>, broadcast through %1 nodes</source>
- <translation>, emitido mediante %d nodos</translation>
+ <translation>, emitido mediante %1 nodos</translation>
</message>
<message>
<location filename="../transactiondesc.cpp" line="76"/>
<message>
<location filename="../transactiondesc.cpp" line="149"/>
<source>(%1 matures in %2 more blocks)</source>
- <translation>(%s madura en %d bloques mas)</translation>
+ <translation>(%1 madura en %1 bloques mas)</translation>
</message>
<message>
<location filename="../transactiondesc.cpp" line="153"/>
<message numerus="yes">
<location filename="../transactiontablemodel.cpp" line="274"/>
<source>Open for %n block(s)</source>
- <translation><numerusform>Abierto por %n bloque</numerusform><numerusform>Abierto por %n bloques</numerusform></translation>
+ <translation>
+ <numerusform>Abierto por %n bloque</numerusform>
+ <numerusform>Abierto por %n bloques</numerusform>
+ </translation>
</message>
<message>
<location filename="../transactiontablemodel.cpp" line="277"/>
<message numerus="yes">
<location filename="../transactiontablemodel.cpp" line="295"/>
<source>Mined balance will be available in %n more blocks</source>
- <translation><numerusform>El balance minado estará disponible en %n bloque mas</numerusform><numerusform>El balance minado estará disponible en %n bloques mas</numerusform></translation>
+ <translation>
+ <numerusform>El balance minado estará disponible en %n bloque mas</numerusform>
+ <numerusform>El balance minado estará disponible en %n bloques mas</numerusform>
+ </translation>
</message>
<message>
<location filename="../transactiontablemodel.cpp" line="301"/>
</message>
<message>
<location filename="../bitcoinstrings.cpp" line="12"/>
- <source>Don't generate coins
+ <source>Don't generate coins
</source>
<translation>No generar monedas
</translation>
</message>
<message>
<location filename="../bitcoinstrings.cpp" line="20"/>
- <source>Don't accept connections from outside
+ <source>Don't accept connections from outside
</source>
<translation>No aceptar conexiones desde el exterior
</translation>
</message>
<message>
<location filename="../bitcoinstrings.cpp" line="21"/>
- <source>Don't attempt to use UPnP to map the listening port
+ <source>Don't attempt to use UPnP to map the listening port
</source>
<translation>No intentar usar UPnP para mapear el puerto de entrada
</translation>
</message>
<message>
<location filename="../bitcoinstrings.cpp" line="23"/>
- <source>Fee per KB to add to transactions you send
+ <source>Fee per kB to add to transactions you send
</source>
- <translation>Comisión por KB para agregar a las transacciones que envias
+ <translation>Comisión por kB para agregar a las transacciones que envias
</translation>
</message>
<message>
<message>
<location filename="../bitcoin.cpp" line="145"/>
<source>Bitcoin Qt</source>
- <translation type="unfinished"/>
+ <translation>Bitcoin Qt</translation>
</message>
</context>
-</TS>
\ No newline at end of file
+</TS>
-<?xml version="1.0" ?><!DOCTYPE TS><TS language="es_CL" version="2.0">
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="es_CL">
<defaultcodec>UTF-8</defaultcodec>
<context>
<name>AboutDialog</name>
<message>
<location filename="../bitcoingui.cpp" line="200"/>
<source>E&xit</source>
- <translation type="unfinished"/>
+ <translation>&Salir</translation>
</message>
<message>
<location filename="../bitcoingui.cpp" line="201"/>
<message>
<location filename="../bitcoingui.cpp" line="204"/>
<source>&About %1</source>
- <translation type="unfinished"/>
+ <translation>S&obre %1</translation>
</message>
<message>
<location filename="../bitcoingui.cpp" line="205"/>
<message numerus="yes">
<location filename="../bitcoingui.cpp" line="396"/>
<source>%n active connection(s) to Bitcoin network</source>
- <translation><numerusform>%n conexión activa hacia la red Bitcoin</numerusform><numerusform>%n conexiones activas hacia la red Bitcoin</numerusform></translation>
+ <translation>
+ <numerusform>%n conexión activa hacia la red Bitcoin</numerusform>
+ <numerusform>%n conexiones activas hacia la red Bitcoin</numerusform>
+ </translation>
</message>
<message>
<location filename="../bitcoingui.cpp" line="411"/>
<message numerus="yes">
<location filename="../bitcoingui.cpp" line="428"/>
<source>%n second(s) ago</source>
- <translation><numerusform>Hace %n segundo</numerusform><numerusform>Hace %n segundos</numerusform></translation>
+ <translation>
+ <numerusform>Hace %n segundo</numerusform>
+ <numerusform>Hace %n segundos</numerusform>
+ </translation>
</message>
<message numerus="yes">
<location filename="../bitcoingui.cpp" line="432"/>
<source>%n minute(s) ago</source>
- <translation><numerusform>Hace %n minuto</numerusform><numerusform>Hace %n minutos</numerusform></translation>
+ <translation>
+ <numerusform>Hace %n minuto</numerusform>
+ <numerusform>Hace %n minutos</numerusform>
+ </translation>
</message>
<message numerus="yes">
<location filename="../bitcoingui.cpp" line="436"/>
<source>%n hour(s) ago</source>
- <translation><numerusform>Hace %n hora</numerusform><numerusform>Hace %n horas</numerusform></translation>
+ <translation>
+ <numerusform>Hace %n hora</numerusform>
+ <numerusform>Hace %n horas</numerusform>
+ </translation>
</message>
<message numerus="yes">
<location filename="../bitcoingui.cpp" line="440"/>
<source>%n day(s) ago</source>
- <translation><numerusform>Hace %n día</numerusform><numerusform>Hace %n días</numerusform></translation>
+ <translation>
+ <numerusform>Hace %n día</numerusform>
+ <numerusform>Hace %n días</numerusform>
+ </translation>
</message>
<message>
<location filename="../bitcoingui.cpp" line="446"/>
</message>
<message>
<location filename="../optionsdialog.cpp" line="217"/>
- <source>Optional transaction fee per KB that helps make sure your transactions are processed quickly. Most transactions are 1KB. Fee 0.01 recommended.</source>
- <translation>Comisión de operación opcional por KB que ayuda a asegurar que tus transacciones sean procesadas rápidamente. La mayoría de las transacciones son de 1KB. Se recomienda una comisión de 0.01.</translation>
+ <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1kB. Fee 0.01 recommended.</source>
+ <translation>Comisión de operación opcional por kB que ayuda a asegurar que tus transacciones sean procesadas rápidamente. La mayoría de las transacciones son de 1kB. Se recomienda una comisión de 0.01.</translation>
</message>
<message>
<location filename="../optionsdialog.cpp" line="223"/>
</message>
<message>
<location filename="../optionsdialog.cpp" line="226"/>
- <source>Optional transaction fee per KB that helps make sure your transactions are processed quickly. Most transactions are 1KB. Fee 0.01 recommended.</source>
- <translation>Comisión de operación opcional por KB que ayuda a asegurar que tus transacciones sean procesadas rápidamente. La mayoría de las transacciones son de 1KB. Se recomienda una comisión de 0.01.</translation>
+ <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1kB. Fee 0.01 recommended.</source>
+ <translation>Comisión de operación opcional por kB que ayuda a asegurar que tus transacciones sean procesadas rápidamente. La mayoría de las transacciones son de 1kB. Se recomienda una comisión de 0.01.</translation>
</message>
</context>
<context>
<source><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
p, li { white-space: pre-wrap; }
-</style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;">
+</style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;">
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Wallet</span></p></body></html></source>
<translation><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
p, li { white-space: pre-wrap; }
-</style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;">
+</style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;">
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Cartera</span></p></body></html></translation>
</message>
<message>
</message>
<message>
<location filename="../forms/sendcoinsentry.ui" line="103"/>
- <source>Choose adress from address book</source>
+ <source>Choose address from address book</source>
<translation>Elije dirección de la guia</translation>
</message>
<message>
<message>
<location filename="../transactiondesc.cpp" line="70"/>
<source>, broadcast through %1 node</source>
- <translation>, emitido mediante %d nodo</translation>
+ <translation>, emitido mediante %1 nodo</translation>
</message>
<message>
<location filename="../transactiondesc.cpp" line="72"/>
<source>, broadcast through %1 nodes</source>
- <translation>, emitido mediante %d nodos</translation>
+ <translation>, emitido mediante %1 nodos</translation>
</message>
<message>
<location filename="../transactiondesc.cpp" line="76"/>
<message>
<location filename="../transactiondesc.cpp" line="149"/>
<source>(%1 matures in %2 more blocks)</source>
- <translation>(%s madura en %d bloques mas)</translation>
+ <translation>(%1 madura en %2 bloques mas)</translation>
</message>
<message>
<location filename="../transactiondesc.cpp" line="153"/>
<message numerus="yes">
<location filename="../transactiontablemodel.cpp" line="274"/>
<source>Open for %n block(s)</source>
- <translation><numerusform>Abierto por %n bloque</numerusform><numerusform>Abierto por %n bloques</numerusform></translation>
+ <translation>
+ <numerusform>Abierto por %n bloque</numerusform>
+ <numerusform>Abierto por %n bloques</numerusform>
+ </translation>
</message>
<message>
<location filename="../transactiontablemodel.cpp" line="277"/>
<message numerus="yes">
<location filename="../transactiontablemodel.cpp" line="295"/>
<source>Mined balance will be available in %n more blocks</source>
- <translation><numerusform>El balance minado estará disponible en %n bloque mas</numerusform><numerusform>El balance minado estará disponible en %n bloques mas</numerusform></translation>
+ <translation>
+ <numerusform>El balance minado estará disponible en %n bloque mas</numerusform>
+ <numerusform>El balance minado estará disponible en %n bloques mas</numerusform>
+ </translation>
</message>
<message>
<location filename="../transactiontablemodel.cpp" line="301"/>
</message>
<message>
<location filename="../bitcoinstrings.cpp" line="12"/>
- <source>Don't generate coins
+ <source>Don't generate coins
</source>
<translation>No generar monedas
</translation>
</message>
<message>
<location filename="../bitcoinstrings.cpp" line="20"/>
- <source>Don't accept connections from outside
+ <source>Don't accept connections from outside
</source>
<translation>No aceptar conexiones desde el exterior
</translation>
</message>
<message>
<location filename="../bitcoinstrings.cpp" line="21"/>
- <source>Don't attempt to use UPnP to map the listening port
+ <source>Don't attempt to use UPnP to map the listening port
</source>
<translation>No intentar usar UPnP para mapear el puerto de entrada
</translation>
</message>
<message>
<location filename="../bitcoinstrings.cpp" line="23"/>
- <source>Fee per KB to add to transactions you send
+ <source>Fee per kB to add to transactions you send
</source>
- <translation>Comisión por KB para agregar a las transacciones que envias
+ <translation>Comisión por kB para agregar a las transacciones que envias
</translation>
</message>
<message>
<message>
<location filename="../bitcoin.cpp" line="145"/>
<source>Bitcoin Qt</source>
- <translation type="unfinished"/>
+ <translation>Bitcoin Qt</translation>
</message>
</context>
-</TS>
\ No newline at end of file
+</TS>
</message>
<message>
<location filename="../optionsdialog.cpp" line="217"/>
- <source>Optional transaction fee per KB that helps make sure your transactions are processed quickly. Most transactions are 1KB. Fee 0.01 recommended.</source>
- <translation>Valgfritt transaksjonsgebyr per KB som hjelper for å sikre at transaksjonene dine blir raskt prosessert. De fleste transaksjoner er 1KB. Et gebyr på 0.01 anbefales.</translation>
+ <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1kB. Fee 0.01 recommended.</source>
+ <translation>Valgfritt transaksjonsgebyr per kB som hjelper for å sikre at transaksjonene dine blir raskt prosessert. De fleste transaksjoner er 1kB. Et gebyr på 0.01 anbefales.</translation>
</message>
<message>
<location filename="../optionsdialog.cpp" line="223"/>
</message>
<message>
<location filename="../optionsdialog.cpp" line="226"/>
- <source>Optional transaction fee per KB that helps make sure your transactions are processed quickly. Most transactions are 1KB. Fee 0.01 recommended.</source>
- <translation>Valgfritt transaksjonsgebyr per KB som hjelper for å sikre at transaksjonene dine blir raskt prosessert. De fleste transaksjoner er 1KB. Et gebyr på 0.01 anbefales.</translation>
+ <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1kB. Fee 0.01 recommended.</source>
+ <translation>Valgfritt transaksjonsgebyr per kB som hjelper for å sikre at transaksjonene dine blir raskt prosessert. De fleste transaksjoner er 1kB. Et gebyr på 0.01 anbefales.</translation>
</message>
</context>
<context>
</message>
<message>
<location filename="../forms/sendcoinsentry.ui" line="103"/>
- <source>Choose adress from address book</source>
+ <source>Choose address from address book</source>
<translation>Velg adresse fra adresseboken</translation>
</message>
<message>
</message>
<message>
<location filename="../bitcoinstrings.cpp" line="23"/>
- <source>Fee per KB to add to transactions you send
+ <source>Fee per kB to add to transactions you send
</source>
- <translation>Gebyr per KB som skal legges til transaksjoner du sender
+ <translation>Gebyr per kB som skal legges til transaksjoner du sender
</translation>
</message>
<message>
</message>
<message>
<location filename="../optionsdialog.cpp" line="217"/>
- <source>Optional transaction fee per KB that helps make sure your transactions are processed quickly. Most transactions are 1KB. Fee 0.01 recommended.</source>
- <translation>Optionele transactiekosten per KB die helpen ervoor te zorgen dat uw transacties snel verwerkt worden. De meeste transacties zijn 1KB. Transactiekosten van 0.01 wordt aangeraden.</translation>
+ <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1kB. Fee 0.01 recommended.</source>
+ <translation>Optionele transactiekosten per kB die helpen ervoor te zorgen dat uw transacties snel verwerkt worden. De meeste transacties zijn 1kB. Transactiekosten van 0.01 wordt aangeraden.</translation>
</message>
<message>
<location filename="../optionsdialog.cpp" line="223"/>
</message>
<message>
<location filename="../optionsdialog.cpp" line="226"/>
- <source>Optional transaction fee per KB that helps make sure your transactions are processed quickly. Most transactions are 1KB. Fee 0.01 recommended.</source>
- <translation>Optionele transactiekosten per KB die helpen ervoor te zorgen dat uw transacties snel verwerkt worden. De meeste transacties zijn 1KB. Transactiekosten van 0.01 wordt aangeraden.</translation>
+ <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1kB. Fee 0.01 recommended.</source>
+ <translation>Optionele transactiekosten per kB die helpen ervoor te zorgen dat uw transacties snel verwerkt worden. De meeste transacties zijn 1kB. Transactiekosten van 0.01 wordt aangeraden.</translation>
</message>
</context>
<context>
</message>
<message>
<location filename="../forms/sendcoinsentry.ui" line="103"/>
- <source>Choose adress from address book</source>
+ <source>Choose address from address book</source>
<translation>Kies adres uit adresboek</translation>
</message>
<message>
</message>
<message>
<location filename="../bitcoinstrings.cpp" line="23"/>
- <source>Fee per KB to add to transactions you send
+ <source>Fee per kB to add to transactions you send
</source>
- <translation>Kosten per KB om aan transacties toe te voegen die u verstuurt
+ <translation>Kosten per kB om aan transacties toe te voegen die u verstuurt
</translation>
</message>
<message>
</message>
<message>
<location filename="../optionsdialog.cpp" line="217"/>
- <source>Optional transaction fee per KB that helps make sure your transactions are processed quickly. Most transactions are 1KB. Fee 0.01 recommended.</source>
- <translation>Опциональная комиссия за кадый KB транзакции, которое позволяет быть уверенным, что Ваша транзакция будет обработана быстро. Большинство транщакций занимают 1 KB. Рекомендованная комиссия: 0.01 BTC.</translation>
+ <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1kB. Fee 0.01 recommended.</source>
+ <translation>Опциональная комиссия за кадый kB транзакции, которое позволяет быть уверенным, что Ваша транзакция будет обработана быстро. Большинство транщакций занимают 1 kB. Рекомендованная комиссия: 0.01 BTC.</translation>
</message>
<message>
<location filename="../optionsdialog.cpp" line="223"/>
</message>
<message>
<location filename="../optionsdialog.cpp" line="226"/>
- <source>Optional transaction fee per KB that helps make sure your transactions are processed quickly. Most transactions are 1KB. Fee 0.01 recommended.</source>
- <translation>Опциональная комиссия за кадый KB транзакции, которая позволяет быть уверенным, что Ваша транзакция будет обработана быстро. Большинство транзакций занимают 1 KB. Рекомендованная комиссия: 0.01 BTC.</translation>
+ <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1kB. Fee 0.01 recommended.</source>
+ <translation>Опциональная комиссия за кадый kB транзакции, которая позволяет быть уверенным, что Ваша транзакция будет обработана быстро. Большинство транзакций занимают 1 kB. Рекомендованная комиссия: 0.01 BTC.</translation>
</message>
</context>
<context>
</message>
<message>
<location filename="../forms/sendcoinsentry.ui" line="103"/>
- <source>Choose adress from address book</source>
+ <source>Choose address from address book</source>
<translation>Выбрать адрес из адресной книги</translation>
</message>
<message>
</message>
<message>
<location filename="../bitcoinstrings.cpp" line="23"/>
- <source>Fee per KB to add to transactions you send
+ <source>Fee per kB to add to transactions you send
</source>
- <translation>Комиссия (за каждый KB транзакции)
+ <translation>Комиссия (за каждый kB транзакции)
</translation>
</message>
<message>
</message>
<message>
<location filename="../optionsdialog.cpp" line="217"/>
- <source>Optional transaction fee per KB that helps make sure your transactions are processed quickly. Most transactions are 1KB. Fee 0.01 recommended.</source>
- <translation>非必要的交易手續費, 有助於縮短你的交易處理時間. 以 KB 為計費單位, 而大部份交易的大小是 1KB. 建議設定為 0.01 位元幣.</translation>
+ <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1kB. Fee 0.01 recommended.</source>
+ <translation>非必要的交易手續費, 有助於縮短你的交易處理時間. 以 kB 為計費單位, 而大部份交易的大小是 1kB. 建議設定為 0.01 位元幣.</translation>
</message>
<message>
<location filename="../optionsdialog.cpp" line="223"/>
</message>
<message>
<location filename="../optionsdialog.cpp" line="226"/>
- <source>Optional transaction fee per KB that helps make sure your transactions are processed quickly. Most transactions are 1KB. Fee 0.01 recommended.</source>
- <translation>非必要的交易手續費, 有助於縮短你的交易處理時間. 以 KB 為計費單位, 而大部份交易的大小是 1KB. 建議設定為 0.01 位元幣.</translation>
+ <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1kB. Fee 0.01 recommended.</source>
+ <translation>非必要的交易手續費, 有助於縮短你的交易處理時間. 以 kB 為計費單位, 而大部份交易的大小是 1kB. 建議設定為 0.01 位元幣.</translation>
</message>
</context>
<context>
</message>
<message>
<location filename="../forms/sendcoinsentry.ui" line="103"/>
- <source>Choose adress from address book</source>
+ <source>Choose address from address book</source>
<translation>從位址簿中選一個位址</translation>
</message>
<message>
</message>
<message>
<location filename="../bitcoinstrings.cpp" line="23"/>
- <source>Fee per KB to add to transactions you send
+ <source>Fee per kB to add to transactions you send
</source>
- <translation>交易付款時每 KB 的交易手續費
+ <translation>交易付款時每 kB 的交易手續費
</translation>
</message>
<message>
proxy_hbox->addStretch(1);
layout->addLayout(proxy_hbox);
- QLabel *fee_help = new QLabel(tr("Optional transaction fee per KB that helps make sure your transactions are processed quickly. Most transactions are 1KB. Fee 0.01 recommended."));
+ QLabel *fee_help = new QLabel(tr("Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB. Fee 0.01 recommended."));
fee_help->setWordWrap(true);
layout->addWidget(fee_help);
QLabel *fee_label = new QLabel(tr("Pay transaction &fee"));
fee_hbox->addWidget(fee_label);
fee_edit = new BitcoinAmountField();
- fee_edit->setToolTip(tr("Optional transaction fee per KB that helps make sure your transactions are processed quickly. Most transactions are 1KB. Fee 0.01 recommended."));
+ fee_edit->setToolTip(tr("Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB. Fee 0.01 recommended."));
fee_label->setBuddy(fee_edit);
fee_hbox->addWidget(fee_edit);
ui->labelNumTransactions->setToolTip(tr("Total number of transactions in wallet"));
// Recent transactions
- ui->listTransactions->setStyleSheet("background:transparent");
+ ui->listTransactions->setStyleSheet("QListView { background:transparent }");
ui->listTransactions->setItemDelegate(txdelegate);
ui->listTransactions->setIconSize(QSize(DECORATION_SIZE, DECORATION_SIZE));
ui->listTransactions->setSelectionMode(QAbstractItemView::NoSelection);
#include <QMessageBox>
#include <QLocale>
#include <QTextDocument>
+#include <QScrollBar>
SendCoinsDialog::SendCoinsDialog(QWidget *parent) :
QDialog(parent),
// Focus the field, so that entry can start immediately
entry->clear();
+ entry->setFocus();
+ ui->scrollAreaWidgetContents->resize(ui->scrollAreaWidgetContents->sizeHint());
+ QCoreApplication::instance()->processEvents();
+ QScrollBar* bar = ui->scrollArea->verticalScrollBar();
+ if (bar)
+ bar->setSliderPosition(bar->maximum());
return entry;
}
pasteEntry(rv);
}
+void SendCoinsDialog::handleURL(const QString &url)
+{
+ SendCoinsRecipient rv;
+ if(!GUIUtil::parseBitcoinURL(url, &rv))
+ {
+ return;
+ }
+ pasteEntry(rv);
+}
+
void SendCoinsDialog::setBalance(qint64 balance, qint64 unconfirmedBalance)
{
Q_UNUSED(unconfirmedBalance);
void pasteEntry(const SendCoinsRecipient &rv);
void handleURL(const QUrl *url);
+ void handleURL(const QString &url);
public slots:
void clear();
{
if(!model)
return;
- ui->addAsLabel->setText(model->getAddressTableModel()->labelForAddress(address));
-}
+ // Fill in label from address book, if no label is filled in yet
+ if(ui->addAsLabel->text().isEmpty())
+ ui->addAsLabel->setText(model->getAddressTableModel()->labelForAddress(address));}
void SendCoinsEntry::setModel(WalletModel *model)
{
this->model = model;
+ clear();
}
void SendCoinsEntry::setRemoveEnabled(bool enabled)
return ui->payTo->text().isEmpty();
}
+void SendCoinsEntry::setFocus()
+{
+ ui->payTo->setFocus();
+}
+
// Hence we have to set it up manually
QWidget *setupTabChain(QWidget *prev);
+ void setFocus();
+
public slots:
void setRemoveEnabled(bool enabled);
void clear();
return false;
if(datetime < dateFrom || datetime > dateTo)
return false;
- if(!address.startsWith(addrPrefix) && !label.startsWith(addrPrefix))
+ if (!address.contains(addrPrefix, Qt::CaseInsensitive) && !label.contains(addrPrefix, Qt::CaseInsensitive))
return false;
if(amount < minAmount)
return false;
// Set maximum number of rows returned, -1 if unlimited
void setLimit(int limit);
- int rowCount(const QModelIndex &parent = QModelIndex()) const;
+ int rowCount(const QModelIndex &parent = QModelIndex()) const;
protected:
bool filterAcceptsRow(int source_row, const QModelIndex & source_parent) const;
//
// Credit
//
- TransactionRecord sub(hash, nTime);
-
- sub.credit = nNet;
-
- if (wtx.IsCoinBase())
- {
- // Generated
- sub.type = TransactionRecord::Generated;
-
- if (nCredit == 0)
- {
- int64 nUnmatured = 0;
- BOOST_FOREACH(const CTxOut& txout, wtx.vout)
- nUnmatured += wallet->GetCredit(txout);
- sub.credit = nUnmatured;
- }
- }
- else if (!mapValue["from"].empty() || !mapValue["message"].empty())
- {
- // Received by IP connection
- sub.type = TransactionRecord::RecvFromIP;
- if (!mapValue["from"].empty())
- sub.address = mapValue["from"];
- }
- else
+ BOOST_FOREACH(const CTxOut& txout, wtx.vout)
{
- // Received by Bitcoin Address
- sub.type = TransactionRecord::RecvWithAddress;
- BOOST_FOREACH(const CTxOut& txout, wtx.vout)
+ if(wallet->IsMine(txout))
{
- if(wallet->IsMine(txout))
+ TransactionRecord sub(hash, nTime);
+ CBitcoinAddress address;
+ sub.idx = parts.size(); // sequence number
+ sub.credit = txout.nValue;
+ if (wtx.IsCoinBase())
{
- CBitcoinAddress address;
- if (ExtractAddress(txout.scriptPubKey, wallet, address))
- {
- sub.address = address.ToString();
- }
- break;
+ // Generated
+ sub.type = TransactionRecord::Generated;
}
+ else if (ExtractAddress(txout.scriptPubKey, wallet, address))
+ {
+ // Received by Bitcoin Address
+ sub.type = TransactionRecord::RecvWithAddress;
+ sub.address = address.ToString();
+ }
+ else
+ {
+ // Received by IP connection (deprecated features), or a multisignature or other non-simple transaction
+ sub.type = TransactionRecord::RecvFromOther;
+ sub.address = mapValue["from"];
+ }
+
+ parts.append(sub);
}
}
- parts.append(sub);
}
else
{
// from a transaction sent back to our own address.
continue;
}
- else if(!mapValue["to"].empty())
+
+ CBitcoinAddress address;
+ if (ExtractAddress(txout.scriptPubKey, 0, address))
{
- // Sent to IP
- sub.type = TransactionRecord::SendToIP;
- sub.address = mapValue["to"];
+ // Sent to Bitcoin Address
+ sub.type = TransactionRecord::SendToAddress;
+ sub.address = address.ToString();
}
else
{
- // Sent to Bitcoin Address
- sub.type = TransactionRecord::SendToAddress;
- CBitcoinAddress address;
- if (ExtractAddress(txout.scriptPubKey, 0, address))
- {
- sub.address = address.ToString();
- }
+ // Sent to IP, or other non-address transaction like OP_EVAL
+ sub.type = TransactionRecord::SendToOther;
+ sub.address = mapValue["to"];
}
int64 nValue = txout.nValue;
Other,
Generated,
SendToAddress,
- SendToIP,
+ SendToOther,
RecvWithAddress,
- RecvFromIP,
+ RecvFromOther,
SendToSelf
};
}
if(wtx->type == TransactionRecord::Generated)
{
- status += "\n";
switch(wtx->status.maturity)
{
case TransactionStatus::Immature:
- status += tr("Mined balance will be available in %n more blocks", "",
+ status += "\n" + tr("Mined balance will be available in %n more blocks", "",
wtx->status.matures_in);
break;
case TransactionStatus::Mature:
break;
case TransactionStatus::MaturesWarning:
- status += tr("This block was not received by any other nodes and will probably not be accepted!");
+ status += "\n" + tr("This block was not received by any other nodes and will probably not be accepted!");
break;
case TransactionStatus::NotAccepted:
- status += tr("Generated but not accepted");
+ status += "\n" + tr("Generated but not accepted");
break;
}
}
{
case TransactionRecord::RecvWithAddress:
return tr("Received with");
- case TransactionRecord::RecvFromIP:
- return tr("Received from IP");
+ case TransactionRecord::RecvFromOther:
+ return tr("Received from");
case TransactionRecord::SendToAddress:
+ case TransactionRecord::SendToOther:
return tr("Sent to");
- case TransactionRecord::SendToIP:
- return tr("Sent to IP");
case TransactionRecord::SendToSelf:
return tr("Payment to yourself");
case TransactionRecord::Generated:
case TransactionRecord::Generated:
return QIcon(":/icons/tx_mined");
case TransactionRecord::RecvWithAddress:
- case TransactionRecord::RecvFromIP:
+ case TransactionRecord::RecvFromOther:
return QIcon(":/icons/tx_input");
case TransactionRecord::SendToAddress:
- case TransactionRecord::SendToIP:
+ case TransactionRecord::SendToOther:
return QIcon(":/icons/tx_output");
default:
return QIcon(":/icons/tx_inout");
{
switch(wtx->type)
{
- case TransactionRecord::RecvFromIP:
+ case TransactionRecord::RecvFromOther:
return QString::fromStdString(wtx->address);
case TransactionRecord::RecvWithAddress:
case TransactionRecord::SendToAddress:
return lookupAddress(wtx->address, tooltip);
- case TransactionRecord::SendToIP:
+ case TransactionRecord::SendToOther:
return QString::fromStdString(wtx->address);
case TransactionRecord::SendToSelf:
case TransactionRecord::Generated:
QString TransactionTableModel::formatTooltip(const TransactionRecord *rec) const
{
QString tooltip = formatTxStatus(rec) + QString("\n") + formatTxType(rec);
- if(rec->type==TransactionRecord::RecvFromIP || rec->type==TransactionRecord::SendToIP ||
+ if(rec->type==TransactionRecord::RecvFromOther || rec->type==TransactionRecord::SendToOther ||
rec->type==TransactionRecord::SendToAddress || rec->type==TransactionRecord::RecvWithAddress)
{
tooltip += QString(" ") + formatTxToAddress(rec, true);
#include "transactiondescdialog.h"
#include "editaddressdialog.h"
#include "optionsmodel.h"
+#include "guiutil.h"
#include <QScrollBar>
#include <QComboBox>
#include <QTableView>
#include <QHeaderView>
#include <QPushButton>
-#include <QFileDialog>
#include <QMessageBox>
#include <QPoint>
#include <QMenu>
typeWidget->addItem(tr("All"), TransactionFilterProxy::ALL_TYPES);
typeWidget->addItem(tr("Received with"), TransactionFilterProxy::TYPE(TransactionRecord::RecvWithAddress) |
- TransactionFilterProxy::TYPE(TransactionRecord::RecvFromIP));
+ TransactionFilterProxy::TYPE(TransactionRecord::RecvFromOther));
typeWidget->addItem(tr("Sent to"), TransactionFilterProxy::TYPE(TransactionRecord::SendToAddress) |
- TransactionFilterProxy::TYPE(TransactionRecord::SendToIP));
+ TransactionFilterProxy::TYPE(TransactionRecord::SendToOther));
typeWidget->addItem(tr("To yourself"), TransactionFilterProxy::TYPE(TransactionRecord::SendToSelf));
typeWidget->addItem(tr("Mined"), TransactionFilterProxy::TYPE(TransactionRecord::Generated));
typeWidget->addItem(tr("Other"), TransactionFilterProxy::TYPE(TransactionRecord::Other));
void TransactionView::exportClicked()
{
// CSV is currently the only supported format
- QString filename = QFileDialog::getSaveFileName(
+ QString filename = GUIUtil::getSaveFileName(
this,
- tr("Export Transaction Data"),
- QDir::currentPath(),
+ tr("Export Transaction Data"), QString(),
tr("Comma separated file (*.csv)"));
if (filename.isNull()) return;
}
}
-bool WalletModel::setWalletEncrypted(bool encrypted, const std::string &passphrase)
+bool WalletModel::setWalletEncrypted(bool encrypted, const SecureString &passphrase)
{
if(encrypted)
{
}
}
-bool WalletModel::setWalletLocked(bool locked, const std::string &passPhrase)
+bool WalletModel::setWalletLocked(bool locked, const SecureString &passPhrase)
{
if(locked)
{
}
}
-bool WalletModel::changePassphrase(const std::string &oldPass, const std::string &newPass)
+bool WalletModel::changePassphrase(const SecureString &oldPass, const SecureString &newPass)
{
bool retval;
CRITICAL_BLOCK(wallet->cs_wallet)
#define WALLETMODEL_H
#include <QObject>
-#include <string>
+
+#include "util.h"
class OptionsModel;
class AddressTableModel;
SendCoinsReturn sendCoins(const QList<SendCoinsRecipient> &recipients);
// Wallet encryption
- bool setWalletEncrypted(bool encrypted, const std::string &passphrase);
+ bool setWalletEncrypted(bool encrypted, const SecureString &passphrase);
// Passphrase only needed when unlocking
- bool setWalletLocked(bool locked, const std::string &passPhrase=std::string());
- bool changePassphrase(const std::string &oldPass, const std::string &newPass);
+ bool setWalletLocked(bool locked, const SecureString &passPhrase=SecureString());
+ bool changePassphrase(const SecureString &oldPass, const SecureString &newPass);
// RAI object for unlocking wallet, returned by requestUnlock()
class UnlockContext
#define wxHELP 0x00008000
#define wxMORE 0x00010000
#define wxSETUP 0x00020000
+// Force blocking, modal message box dialog (not just notification)
+#define wxMODAL 0x00040000
extern int MyMessageBox(const std::string& message, const std::string& caption="Message", int style=wxOK, wxWindow* parent=NULL, int x=-1, int y=-1);
#define wxMessageBox MyMessageBox
}
-bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn, int nHashType)
+bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn,
+ bool fValidatePayToScriptHash, int nHashType)
{
- vector<vector<unsigned char> > stack;
+ vector<vector<unsigned char> > stack, stackCopy;
if (!EvalScript(stack, scriptSig, txTo, nIn, nHashType))
return false;
+ if (fValidatePayToScriptHash)
+ stackCopy = stack;
if (!EvalScript(stack, scriptPubKey, txTo, nIn, nHashType))
return false;
if (stack.empty())
return false;
- return CastToBool(stack.back());
+
+ if (CastToBool(stack.back()) == false)
+ return false;
+
+ // Additional validation for spend-to-script-hash transactions:
+ if (fValidatePayToScriptHash && scriptPubKey.IsPayToScriptHash())
+ {
+ if (!scriptSig.IsPushOnly()) // scriptSig must be literals-only
+ return false; // or validation fails
+
+ const valtype& pubKeySerialized = stackCopy.back();
+ CScript pubKey2(pubKeySerialized.begin(), pubKeySerialized.end());
+ popstack(stackCopy);
+
+ if (!EvalScript(stackCopy, pubKey2, txTo, nIn, nHashType))
+ return false;
+ if (stackCopy.empty())
+ return false;
+ return CastToBool(stackCopy.back());
+ }
+
+ return true;
}
// Test solution
if (scriptPrereq.empty())
- if (!VerifyScript(txin.scriptSig, txout.scriptPubKey, txTo, nIn, 0))
+ if (!VerifyScript(txin.scriptSig, txout.scriptPubKey, txTo, nIn, true, 0))
return false;
return true;
}
-bool VerifySignature(const CTransaction& txFrom, const CTransaction& txTo, unsigned int nIn, int nHashType)
+bool VerifySignature(const CTransaction& txFrom, const CTransaction& txTo, unsigned int nIn, bool fValidatePayToScriptHash, int nHashType)
{
assert(nIn < txTo.vin.size());
const CTxIn& txin = txTo.vin[nIn];
if (txin.prevout.hash != txFrom.GetHash())
return false;
- if (!VerifyScript(txin.scriptSig, txout.scriptPubKey, txTo, nIn, nHashType))
+ if (!VerifyScript(txin.scriptSig, txout.scriptPubKey, txTo, nIn, fValidatePayToScriptHash, nHashType))
return false;
return true;
}
+
+int CScript::GetSigOpCount(bool fAccurate) const
+{
+ int n = 0;
+ const_iterator pc = begin();
+ opcodetype lastOpcode = OP_INVALIDOPCODE;
+ while (pc < end())
+ {
+ opcodetype opcode;
+ if (!GetOp(pc, opcode))
+ break;
+ if (opcode == OP_CHECKSIG || opcode == OP_CHECKSIGVERIFY)
+ n++;
+ else if (opcode == OP_CHECKMULTISIG || opcode == OP_CHECKMULTISIGVERIFY)
+ {
+ if (fAccurate && lastOpcode >= OP_1 && lastOpcode <= OP_16)
+ n += DecodeOP_N(lastOpcode);
+ else
+ n += 20;
+ }
+ lastOpcode = opcode;
+ }
+ return n;
+}
+
+int CScript::GetSigOpCount(const CScript& scriptSig) const
+{
+ if (!IsPayToScriptHash())
+ return GetSigOpCount(true);
+
+ // This is a pay-to-script-hash scriptPubKey;
+ // get the last item that the scriptSig
+ // pushes onto the stack:
+ const_iterator pc = scriptSig.begin();
+ vector<unsigned char> data;
+ while (pc < scriptSig.end())
+ {
+ opcodetype opcode;
+ if (!scriptSig.GetOp(pc, opcode, data))
+ return 0;
+ if (opcode > OP_16)
+ return 0;
+ }
+
+ /// ... and return it's opcount:
+ CScript subscript(data.begin(), data.end());
+ return subscript.GetSigOpCount(true);
+}
+
+bool CScript::IsPayToScriptHash() const
+{
+ // Extra-fast test for pay-to-script-hash CScripts:
+ return (this->size() == 23 &&
+ this->at(0) == OP_HASH160 &&
+ this->at(1) == 0x14 &&
+ this->at(22) == OP_EQUAL);
+}
return true;
}
+ // Encode/decode small integers:
+ static int DecodeOP_N(opcodetype opcode)
+ {
+ if (opcode == OP_0)
+ return 0;
+ assert(opcode >= OP_1 && opcode <= OP_16);
+ return (int)opcode - (int)(OP_1 - 1);
+ }
void FindAndDelete(const CScript& b)
{
}
while (GetOp(pc, opcode));
}
-
-
- int GetSigOpCount() const
+ int Find(opcodetype op) const
{
- int n = 0;
- const_iterator pc = begin();
- while (pc < end())
- {
- opcodetype opcode;
- if (!GetOp(pc, opcode))
- break;
- if (opcode == OP_CHECKSIG || opcode == OP_CHECKSIGVERIFY)
- n++;
- else if (opcode == OP_CHECKMULTISIG || opcode == OP_CHECKMULTISIGVERIFY)
- n += 20;
- }
- return n;
+ int nFound = 0;
+ opcodetype opcode;
+ for (const_iterator pc = begin(); pc != end() && GetOp(pc, opcode);)
+ if (opcode == op)
+ ++nFound;
+ return nFound;
}
+ // Pre-version-0.6, Bitcoin always counted CHECKMULTISIGs
+ // as 20 sigops. With pay-to-script-hash, that changed:
+ // CHECKMULTISIGs serialized in scriptSigs are
+ // counted more accurately, assuming they are of the form
+ // ... OP_N CHECKMULTISIG ...
+ int GetSigOpCount(bool fAccurate=false) const;
+
+ // Accurately count sigOps, including sigOps in
+ // pay-to-script-hash transactions:
+ int GetSigOpCount(const CScript& scriptSig) const;
+
+ bool IsPayToScriptHash() const;
bool IsPushOnly() const
{
bool IsMine(const CKeyStore& keystore, const CScript& scriptPubKey);
bool ExtractAddress(const CScript& scriptPubKey, const CKeyStore* pkeystore, CBitcoinAddress& addressRet);
bool SignSignature(const CKeyStore& keystore, const CTransaction& txFrom, CTransaction& txTo, unsigned int nIn, int nHashType=SIGHASH_ALL, CScript scriptPrereq=CScript());
-bool VerifySignature(const CTransaction& txFrom, const CTransaction& txTo, unsigned int nIn, int nHashType=0);
+bool VerifySignature(const CTransaction& txFrom, const CTransaction& txTo, unsigned int nIn, bool fValidatePayToScriptHash, int nHashType);
#endif
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2011 The Bitcoin developers
+// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_SERIALIZE_H
class CAutoFile;
static const unsigned int MAX_SIZE = 0x02000000;
-static const int VERSION = 50001;
+static const int VERSION = 50006;
static const char* pszSubVer = "";
static const bool VERSION_IS_BETA = true;
const bool fRead = false; \
unsigned int nSerSize = 0; \
ser_streamplaceholder s; \
+ assert(fGetSize||fWrite||fRead); /* suppress warning */ \
s.nType = nType; \
s.nVersion = nVersion; \
{statements} \
const bool fWrite = true; \
const bool fRead = false; \
unsigned int nSerSize = 0; \
+ assert(fGetSize||fWrite||fRead); /* suppress warning */ \
{statements} \
} \
template<typename Stream> \
const bool fWrite = false; \
const bool fRead = true; \
unsigned int nSerSize = 0; \
+ assert(fGetSize||fWrite||fRead); /* suppress warning */ \
{statements} \
}
};
+//
+// Allocator that clears its contents before deletion.
+//
+template<typename T>
+struct zero_after_free_allocator : public std::allocator<T>
+{
+ // MSVC8 default copy constructor is broken
+ typedef std::allocator<T> base;
+ typedef typename base::size_type size_type;
+ typedef typename base::difference_type difference_type;
+ typedef typename base::pointer pointer;
+ typedef typename base::const_pointer const_pointer;
+ typedef typename base::reference reference;
+ typedef typename base::const_reference const_reference;
+ typedef typename base::value_type value_type;
+ zero_after_free_allocator() throw() {}
+ zero_after_free_allocator(const zero_after_free_allocator& a) throw() : base(a) {}
+ template <typename U>
+ zero_after_free_allocator(const zero_after_free_allocator<U>& a) throw() : base(a) {}
+ ~zero_after_free_allocator() throw() {}
+ template<typename _Other> struct rebind
+ { typedef zero_after_free_allocator<_Other> other; };
+
+ void deallocate(T* p, std::size_t n)
+ {
+ if (p != NULL)
+ memset(p, 0, sizeof(T) * n);
+ std::allocator<T>::deallocate(p, n);
+ }
+};
+
+
//
// Double ended buffer combining vector and stream-like interfaces.
class CDataStream
{
protected:
- typedef std::vector<char, secure_allocator<char> > vector_type;
+ typedef std::vector<char, zero_after_free_allocator<char> > vector_type;
vector_type vch;
unsigned int nReadPos;
short state;
--- /dev/null
+//
+// Unit tests for block-chain checkpoints
+//
+#include <boost/assign/list_of.hpp> // for 'map_list_of()'
+#include <boost/test/unit_test.hpp>
+#include <boost/foreach.hpp>
+
+#include "../checkpoints.h"
+#include "../util.h"
+
+using namespace std;
+
+BOOST_AUTO_TEST_SUITE(Checkpoints_tests)
+
+BOOST_AUTO_TEST_CASE(sanity)
+{
+ uint256 p11111 = uint256("0x0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d");
+ uint256 p140700 = uint256("0x000000000000033b512028abb90e1626d8b346fd0ed598ac0a3c371138dce2bd");
+ BOOST_CHECK(Checkpoints::CheckBlock(11111, p11111));
+ BOOST_CHECK(Checkpoints::CheckBlock(140700, p140700));
+
+
+ // Wrong hashes at checkpoints should fail:
+ BOOST_CHECK(!Checkpoints::CheckBlock(11111, p140700));
+ BOOST_CHECK(!Checkpoints::CheckBlock(140700, p11111));
+
+ // ... but any hash not at a checkpoint should succeed:
+ BOOST_CHECK(Checkpoints::CheckBlock(11111+1, p140700));
+ BOOST_CHECK(Checkpoints::CheckBlock(140700+1, p11111));
+
+ BOOST_CHECK(Checkpoints::GetTotalBlocksEstimate() >= 140700);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
//
// Unit tests for denial-of-service detection/prevention code
//
+#include <boost/assign/list_of.hpp> // for 'map_list_of()'
#include <boost/test/unit_test.hpp>
#include <boost/foreach.hpp>
BOOST_CHECK(!CNode::IsBanned(addr.ip));
}
+static bool CheckNBits(unsigned int nbits1, int64 time1, unsigned int nbits2, int64 time2)
+{
+ if (time1 > time2)
+ return CheckNBits(nbits2, time2, nbits1, time1);
+ int64 deltaTime = time2-time1;
+
+ CBigNum required;
+ required.SetCompact(ComputeMinWork(nbits1, deltaTime));
+ CBigNum have;
+ have.SetCompact(nbits2);
+ return (have <= required);
+}
+
+BOOST_AUTO_TEST_CASE(DoS_checknbits)
+{
+ using namespace boost::assign; // for 'map_list_of()'
+
+ // Timestamps,nBits from the bitcoin blockchain.
+ // These are the block-chain checkpoint blocks
+ typedef std::map<int64, unsigned int> BlockData;
+ BlockData chainData =
+ map_list_of(1239852051,486604799)(1262749024,486594666)
+ (1279305360,469854461)(1280200847,469830746)(1281678674,469809688)
+ (1296207707,453179945)(1302624061,453036989)(1309640330,437004818)
+ (1313172719,436789733);
+
+ // Make sure CheckNBits considers every combination of block-chain-lock-in-points
+ // "sane":
+ BOOST_FOREACH(const BlockData::value_type& i, chainData)
+ {
+ BOOST_FOREACH(const BlockData::value_type& j, chainData)
+ {
+ BOOST_CHECK(CheckNBits(i.second, i.first, j.second, j.first));
+ }
+ }
+
+ // Test a couple of insane combinations:
+ BlockData::value_type firstcheck = *(chainData.begin());
+ BlockData::value_type lastcheck = *(chainData.rbegin());
+
+ // First checkpoint difficulty at or a while after the last checkpoint time should fail when
+ // compared to last checkpoint
+ BOOST_CHECK(!CheckNBits(firstcheck.second, lastcheck.first+60*10, lastcheck.second, lastcheck.first));
+ BOOST_CHECK(!CheckNBits(firstcheck.second, lastcheck.first+60*60*24*14, lastcheck.second, lastcheck.first));
+
+ // ... but OK if enough time passed for difficulty to adjust downward:
+ BOOST_CHECK(CheckNBits(firstcheck.second, lastcheck.first+60*60*24*365*4, lastcheck.second, lastcheck.first));
+
+}
BOOST_AUTO_TEST_SUITE_END()
using namespace std;
extern uint256 SignatureHash(CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType);
-extern bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn, int nHashType);
-extern bool VerifySignature(const CTransaction& txFrom, const CTransaction& txTo, unsigned int nIn, int nHashType);
+extern bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn,
+ bool fValidatePayToScriptHash, int nHashType);
BOOST_AUTO_TEST_SUITE(script_tests)
txTo12.vout[0].nValue = 1;
CScript goodsig1 = sign_multisig(scriptPubKey12, key1, txTo12);
- BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey12, txTo12, 0, 0));
+ BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey12, txTo12, 0, true, 0));
txTo12.vout[0].nValue = 2;
- BOOST_CHECK(!VerifyScript(goodsig1, scriptPubKey12, txTo12, 0, 0));
+ BOOST_CHECK(!VerifyScript(goodsig1, scriptPubKey12, txTo12, 0, true, 0));
CScript goodsig2 = sign_multisig(scriptPubKey12, key2, txTo12);
- BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey12, txTo12, 0, 0));
+ BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey12, txTo12, 0, true, 0));
CScript badsig1 = sign_multisig(scriptPubKey12, key3, txTo12);
- BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey12, txTo12, 0, 0));
+ BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey12, txTo12, 0, true, 0));
}
BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG23)
std::vector<CKey> keys;
keys.push_back(key1); keys.push_back(key2);
CScript goodsig1 = sign_multisig(scriptPubKey23, keys, txTo23);
- BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey23, txTo23, 0, 0));
+ BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey23, txTo23, 0, true, 0));
keys.clear();
keys.push_back(key1); keys.push_back(key3);
CScript goodsig2 = sign_multisig(scriptPubKey23, keys, txTo23);
- BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey23, txTo23, 0, 0));
+ BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey23, txTo23, 0, true, 0));
keys.clear();
keys.push_back(key2); keys.push_back(key3);
CScript goodsig3 = sign_multisig(scriptPubKey23, keys, txTo23);
- BOOST_CHECK(VerifyScript(goodsig3, scriptPubKey23, txTo23, 0, 0));
+ BOOST_CHECK(VerifyScript(goodsig3, scriptPubKey23, txTo23, 0, true, 0));
keys.clear();
keys.push_back(key2); keys.push_back(key2); // Can't re-use sig
CScript badsig1 = sign_multisig(scriptPubKey23, keys, txTo23);
- BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey23, txTo23, 0, 0));
+ BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey23, txTo23, 0, true, 0));
keys.clear();
keys.push_back(key2); keys.push_back(key1); // sigs must be in correct order
CScript badsig2 = sign_multisig(scriptPubKey23, keys, txTo23);
- BOOST_CHECK(!VerifyScript(badsig2, scriptPubKey23, txTo23, 0, 0));
+ BOOST_CHECK(!VerifyScript(badsig2, scriptPubKey23, txTo23, 0, true, 0));
keys.clear();
keys.push_back(key3); keys.push_back(key2); // sigs must be in correct order
CScript badsig3 = sign_multisig(scriptPubKey23, keys, txTo23);
- BOOST_CHECK(!VerifyScript(badsig3, scriptPubKey23, txTo23, 0, 0));
+ BOOST_CHECK(!VerifyScript(badsig3, scriptPubKey23, txTo23, 0, true, 0));
keys.clear();
keys.push_back(key4); keys.push_back(key2); // sigs must match pubkeys
CScript badsig4 = sign_multisig(scriptPubKey23, keys, txTo23);
- BOOST_CHECK(!VerifyScript(badsig4, scriptPubKey23, txTo23, 0, 0));
+ BOOST_CHECK(!VerifyScript(badsig4, scriptPubKey23, txTo23, 0, true, 0));
keys.clear();
keys.push_back(key1); keys.push_back(key4); // sigs must match pubkeys
CScript badsig5 = sign_multisig(scriptPubKey23, keys, txTo23);
- BOOST_CHECK(!VerifyScript(badsig5, scriptPubKey23, txTo23, 0, 0));
+ BOOST_CHECK(!VerifyScript(badsig5, scriptPubKey23, txTo23, 0, true, 0));
keys.clear(); // Must have signatures
CScript badsig6 = sign_multisig(scriptPubKey23, keys, txTo23);
- BOOST_CHECK(!VerifyScript(badsig6, scriptPubKey23, txTo23, 0, 0));
+ BOOST_CHECK(!VerifyScript(badsig6, scriptPubKey23, txTo23, 0, true, 0));
}
#include "util_tests.cpp"
#include "base58_tests.cpp"
#include "miner_tests.cpp"
+#include "Checkpoints_tests.cpp"
CWallet* pwalletMain;
return *this;
}
- base_uint& operator&=(uint64 b)
- {
- pn[0] &= (unsigned int)b;
- pn[1] &= (unsigned int)(b >> 32);
- return *this;
- }
-
base_uint& operator|=(uint64 b)
{
pn[0] |= (unsigned int)b;
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2011 The Bitcoin developers
+// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
#include "headers.h"
}
}
+bool SoftSetArg(const std::string& strArg, const std::string& strValue)
+{
+ if (mapArgs.count(strArg))
+ return false;
+ mapArgs[strArg] = strValue;
+ return true;
+}
+
+bool SoftSetArg(const std::string& strArg, bool fValue)
+{
+ if (fValue)
+ return SoftSetArg(strArg, std::string("1"));
+ else
+ return SoftSetArg(strArg, std::string("0"));
+}
+
+
string EncodeBase64(const unsigned char* pch, size_t len)
{
static const char *pbase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
{
PSHGETSPECIALFOLDERPATHA pSHGetSpecialFolderPath =
(PSHGETSPECIALFOLDERPATHA)GetProcAddress(hShell32, "SHGetSpecialFolderPathA");
+ bool fSuccess = false;
if (pSHGetSpecialFolderPath)
+ fSuccess =
(*pSHGetSpecialFolderPath)(NULL, pszPath, nFolder, fCreate);
FreeModule(hShell32);
+ if (fSuccess)
+ return pszPath;
}
// Backup option
- if (pszPath[0] == '\0')
+ std::string strPath;
{
+ const char *pszEnv;
if (nFolder == CSIDL_STARTUP)
{
- strcpy(pszPath, getenv("USERPROFILE"));
- strcat(pszPath, "\\Start Menu\\Programs\\Startup");
+ pszEnv = getenv("USERPROFILE");
+ if (pszEnv)
+ strPath = pszEnv;
+ strPath += "\\Start Menu\\Programs\\Startup";
}
else if (nFolder == CSIDL_APPDATA)
{
- strcpy(pszPath, getenv("APPDATA"));
+ pszEnv = getenv("APPDATA");
+ if (pszEnv)
+ strPath = pszEnv;
}
}
- return pszPath;
+ return strPath;
}
#endif
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2011 The Bitcoin developers
+// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_UTIL_H
#define Beep(n1,n2) (0)
inline void Sleep(int64 n)
{
- boost::thread::sleep(boost::get_system_time() + boost::posix_time::milliseconds(n));
+ /*Boost has a year 2038 problem— if the request sleep time is past epoch+2^31 seconds the sleep returns instantly.
+ So we clamp our sleeps here to 10 years and hope that boost is fixed by 2028.*/
+ boost::thread::sleep(boost::get_system_time() + boost::posix_time::milliseconds(n>315576000000LL?315576000000LL:n));
}
#endif
for (bool fcriticalblockonce=true; fcriticalblockonce; assert(("break caught by CRITICAL_BLOCK!" && !fcriticalblockonce)), fcriticalblockonce=false) \
for (CCriticalBlock criticalblock(cs, #cs, __FILE__, __LINE__); fcriticalblockonce; fcriticalblockonce=false)
+#define ENTER_CRITICAL_SECTION(cs) \
+ (cs).Enter(#cs, __FILE__, __LINE__)
+
+#define LEAVE_CRITICAL_SECTION(cs) \
+ (cs).Leave()
+
class CTryCriticalBlock
{
protected:
+// This is exactly like std::string, but with a custom allocator.
+// (secure_allocator<> is defined in serialize.h)
+typedef std::basic_string<char, std::char_traits<char>, secure_allocator<char> > SecureString;
+
return nDefault;
}
-inline bool GetBoolArg(const std::string& strArg)
+inline bool GetBoolArg(const std::string& strArg, bool fDefault=false)
{
if (mapArgs.count(strArg))
{
return true;
return (atoi(mapArgs[strArg]) != 0);
}
- return false;
+ return fDefault;
}
+/**
+ * Set an argument if it doesn't already have a value
+ *
+ * @param strArg Argument to set (e.g. "-foo")
+ * @param strValue Value (e.g. "1")
+ * @return true if argument gets set, false if it already had a value
+ */
+bool SoftSetArg(const std::string& strArg, const std::string& strValue);
+
+/**
+ * Set a boolean argument if it doesn't already have a value
+ *
+ * @param strArg Argument to set (e.g. "-foo")
+ * @param fValue Value (e.g. false)
+ * @return true if argument gets set, false if it already had a value
+ */
+bool SoftSetArg(const std::string& strArg, bool fValue);
inline uint32_t ByteReverse(uint32_t value)
{
- value = ((value & 0xFF00FF00) >> 8) | ((value & 0x00FF00FF) << 8);
- return (value<<16) | (value>>16);
+ value = ((value & 0xFF00FF00) >> 8) | ((value & 0x00FF00FF) << 8);
+ return (value<<16) | (value>>16);
}
#endif
return false;
}
-bool CWallet::Unlock(const string& strWalletPassphrase)
+bool CWallet::Unlock(const SecureString& strWalletPassphrase)
{
if (!IsLocked())
return false;
return false;
}
-bool CWallet::ChangeWalletPassphrase(const string& strOldWalletPassphrase, const string& strNewWalletPassphrase)
+bool CWallet::ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase, const SecureString& strNewWalletPassphrase)
{
bool fWasLocked = IsLocked();
)
};
-bool CWallet::EncryptWallet(const string& strWalletPassphrase)
+bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase)
{
if (IsCrypted())
return false;
if (!pwalletdbEncryption->TxnCommit())
exit(1); //We now have keys encrypted in memory, but no on disk...die to avoid confusion and let the user reload their unencrypted wallet.
- pwalletdbEncryption->Close();
+ delete pwalletdbEncryption;
pwalletdbEncryption = NULL;
}
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2011 The Bitcoin developers
+// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_WALLET_H
// Adds an encrypted key to the store, without saving it to disk (used by LoadWallet)
bool LoadCryptedKey(const std::vector<unsigned char> &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret) { return CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret); }
- bool Unlock(const std::string& strWalletPassphrase);
- bool ChangeWalletPassphrase(const std::string& strOldWalletPassphrase, const std::string& strNewWalletPassphrase);
- bool EncryptWallet(const std::string& strWalletPassphrase);
+ bool Unlock(const SecureString& strWalletPassphrase);
+ bool ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase, const SecureString& strNewWalletPassphrase);
+ bool EncryptWallet(const SecureString& strWalletPassphrase);
bool AddToWallet(const CWalletTx& wtxIn);
bool AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pblock, bool fUpdate = false);
bool CreateTransaction(const std::vector<std::pair<CScript, int64> >& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet);
bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet);
bool CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey);
- bool BroadcastTransaction(CWalletTx& wtxNew);
std::string SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false);
std::string SendMoneyToBitcoinAddress(const CBitcoinAddress& address, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false);