diff --git a/README.md b/README.md index cb959c800..a638844f7 100644 --- a/README.md +++ b/README.md @@ -99,3 +99,38 @@ Periodically the translations are pulled from Transifex and merged into the git If the changes are Dogecoin specific, they can be submitted as pull request against this repository. If it is a general translation, consider submitting it through upstream, as we will pull these changes later on. + +Development tips and tricks +--------------------------- + +**compiling for debugging** + +Run configure with the --enable-debug option, then make. Or run configure with +CXXFLAGS="-g -ggdb -O0" or whatever debug flags you need. + +**debug.log** + +If the code is behaving strangely, take a look in the debug.log file in the data directory; +error and debugging message are written there. + +The -debug=... command-line option controls debugging; running with just -debug will turn +on all categories (and give you a very large debug.log file). + +The Qt code routes qDebug() output to debug.log under category "qt": run with -debug=qt +to see it. + +**testnet and regtest modes** + +Run with the -testnet option to run with "play dogecoins" on the test network, if you +are testing multi-machine code that needs to operate across the internet. + +If you are testing something that can run on one machine, run with the -regtest option. +In regression test mode blocks can be created on-demand; see qa/rpc-tests/ for tests +that run in -regest mode. + +**DEBUG_LOCKORDER** + +Dogecoin Core is a multithreaded application, and deadlocks or other multithreading bugs +can be very difficult to track down. Compiling with -DDEBUG_LOCKORDER (configure +CXXFLAGS="-DDEBUG_LOCKORDER -g") inserts run-time checks to keep track of what locks +are held, and adds warning to the debug.log file if inconsistencies are detected. diff --git a/configure.ac b/configure.ac index 5528c4e21..5dd075742 100644 --- a/configure.ac +++ b/configure.ac @@ -303,6 +303,8 @@ INCLUDES="$INCLUDES $PTHREAD_CFLAGS" # they also need to be passed down to any subprojects. Pull the results out of # the cache and add them to CPPFLAGS. AC_SYS_LARGEFILE +# detect POSIX or GNU variant of strerror_r +AC_FUNC_STRERROR_R if test x$ac_cv_sys_file_offset_bits != x && test x$ac_cv_sys_file_offset_bits != xno && diff --git a/contrib/gitian-descriptors/deps-linux.yml b/contrib/gitian-descriptors/deps-linux.yml index 515d08c17..9cd9508c0 100644 --- a/contrib/gitian-descriptors/deps-linux.yml +++ b/contrib/gitian-descriptors/deps-linux.yml @@ -16,7 +16,7 @@ packages: reference_datetime: "2013-06-01 00:00:00" remotes: [] files: -- "openssl-1.0.1g.tar.gz" +- "openssl-1.0.1h.tar.gz" - "miniupnpc-1.9.tar.gz" - "qrencode-3.4.3.tar.bz2" - "protobuf-2.5.0.tar.bz2" @@ -30,15 +30,15 @@ script: | export TZ=UTC export LIBRARY_PATH="$STAGING/lib" # Integrity Check - echo "53cb818c3b90e507a8348f4f5eaedb05d8bfe5358aabb508b7263cc670c3e028 openssl-1.0.1g.tar.gz" | sha256sum -c + echo "9d1c8a9836aa63e2c6adb684186cbd4371c9e9dcc01d6e3bb447abf2d4d3d093 openssl-1.0.1h.tar.gz" | sha256sum -c echo "2923e453e880bb949e3d4da9f83dd3cb6f08946d35de0b864d0339cf70934464 miniupnpc-1.9.tar.gz" | sha256sum -c echo "dfd71487513c871bad485806bfd1fdb304dedc84d2b01a8fb8e0940b50597a98 qrencode-3.4.3.tar.bz2" | sha256sum -c echo "13bfc5ae543cf3aa180ac2485c0bc89495e3ae711fc6fab4f8ffe90dfb4bb677 protobuf-2.5.0.tar.bz2" | sha256sum -c echo "08238e59736d1aacdd47cfb8e68684c695516c37f4fbe1b8267dde58dc3a576c db-5.1.29.NC.tar.gz" | sha256sum -c # - tar xzf openssl-1.0.1g.tar.gz - cd openssl-1.0.1g + tar xzf openssl-1.0.1h.tar.gz + cd openssl-1.0.1h # need -fPIC to avoid relocation error in 64 bit builds ./config no-shared no-zlib no-dso no-krb5 --openssldir=$STAGING -fPIC # need to build OpenSSL with faketime because a timestamp is embedded into cversion.o @@ -95,4 +95,4 @@ script: | done # cd $STAGING - find include lib bin host | sort | zip -X@ $OUTDIR/dogecoin-deps-linux${GBUILD_BITS}-gitian-r5.zip + find include lib bin host | sort | zip -X@ $OUTDIR/dogecoin-deps-linux${GBUILD_BITS}-gitian-r6.zip diff --git a/contrib/gitian-descriptors/deps-win.yml b/contrib/gitian-descriptors/deps-win.yml index af267c99a..c3529c52b 100644 --- a/contrib/gitian-descriptors/deps-win.yml +++ b/contrib/gitian-descriptors/deps-win.yml @@ -14,7 +14,7 @@ packages: reference_datetime: "2011-01-30 00:00:00" remotes: [] files: -- "openssl-1.0.1g.tar.gz" +- "openssl-1.0.1h.tar.gz" - "db-5.1.29.NC.tar.gz" - "miniupnpc-1.9.tar.gz" - "zlib-1.2.8.tar.gz" @@ -28,7 +28,7 @@ script: | INDIR=$HOME/build TEMPDIR=$HOME/tmp # Input Integrity Check - echo "53cb818c3b90e507a8348f4f5eaedb05d8bfe5358aabb508b7263cc670c3e028 openssl-1.0.1g.tar.gz" | sha256sum -c + echo "9d1c8a9836aa63e2c6adb684186cbd4371c9e9dcc01d6e3bb447abf2d4d3d093 openssl-1.0.1h.tar.gz" | sha256sum -c echo "08238e59736d1aacdd47cfb8e68684c695516c37f4fbe1b8267dde58dc3a576c db-5.1.29.NC.tar.gz" | sha256sum -c echo "2923e453e880bb949e3d4da9f83dd3cb6f08946d35de0b864d0339cf70934464 miniupnpc-1.9.tar.gz" | sha256sum -c echo "36658cb768a54c1d4dec43c3116c27ed893e88b02ecfcb44f2166f9c0b7f2a0d zlib-1.2.8.tar.gz" | sha256sum -c @@ -48,8 +48,8 @@ script: | mkdir -p $INSTALLPREFIX $BUILDDIR cd $BUILDDIR # - tar xzf $INDIR/openssl-1.0.1g.tar.gz - cd openssl-1.0.1g + tar xzf $INDIR/openssl-1.0.1h.tar.gz + cd openssl-1.0.1h if [ "$BITS" == "32" ]; then OPENSSL_TGT=mingw else @@ -126,5 +126,5 @@ script: | done # cd $INSTALLPREFIX - find include lib | sort | zip -X@ $OUTDIR/dogecoin-deps-win$BITS-gitian-r12.zip + find include lib | sort | zip -X@ $OUTDIR/dogecoin-deps-win$BITS-gitian-r13.zip done # for BITS in diff --git a/contrib/gitian-descriptors/gitian-linux.yml b/contrib/gitian-descriptors/gitian-linux.yml index 81405c5a5..28a5f8bee 100644 --- a/contrib/gitian-descriptors/gitian-linux.yml +++ b/contrib/gitian-descriptors/gitian-linux.yml @@ -25,8 +25,8 @@ remotes: - "url": "https://github.com/dogecoin/dogecoin.git" "dir": "dogecoin" files: -- "dogecoin-deps-linux32-gitian-r5.zip" -- "dogecoin-deps-linux64-gitian-r5.zip" +- "dogecoin-deps-linux32-gitian-r6.zip" +- "dogecoin-deps-linux64-gitian-r6.zip" - "boost-linux32-1.55.0-gitian-r1.zip" - "boost-linux64-1.55.0-gitian-r1.zip" - "qt-linux32-4.6.4-gitian-r1.tar.gz" @@ -43,7 +43,7 @@ script: | # mkdir -p $STAGING cd $STAGING - unzip ../build/dogecoin-deps-linux${GBUILD_BITS}-gitian-r5.zip + unzip ../build/dogecoin-deps-linux${GBUILD_BITS}-gitian-r6.zip unzip ../build/boost-linux${GBUILD_BITS}-1.55.0-gitian-r1.zip tar -zxf ../build/qt-linux${GBUILD_BITS}-4.6.4-gitian-r1.tar.gz cd ../build diff --git a/contrib/gitian-descriptors/gitian-win.yml b/contrib/gitian-descriptors/gitian-win.yml index 7d00d1a04..61abe9f6c 100644 --- a/contrib/gitian-descriptors/gitian-win.yml +++ b/contrib/gitian-descriptors/gitian-win.yml @@ -26,8 +26,8 @@ files: - "qt-win64-5.2.0-gitian-r3.zip" - "boost-win32-1.55.0-gitian-r6.zip" - "boost-win64-1.55.0-gitian-r6.zip" -- "dogecoin-deps-win32-gitian-r12.zip" -- "dogecoin-deps-win64-gitian-r12.zip" +- "dogecoin-deps-win32-gitian-r13.zip" +- "dogecoin-deps-win64-gitian-r13.zip" - "protobuf-win32-2.5.0-gitian-r4.zip" - "protobuf-win64-2.5.0-gitian-r4.zip" script: | @@ -61,7 +61,7 @@ script: | cd $STAGING unzip $INDIR/qt-win${BITS}-5.2.0-gitian-r3.zip unzip $INDIR/boost-win${BITS}-1.55.0-gitian-r6.zip - unzip $INDIR/dogecoin-deps-win${BITS}-gitian-r12.zip + unzip $INDIR/dogecoin-deps-win${BITS}-gitian-r13.zip unzip $INDIR/protobuf-win${BITS}-2.5.0-gitian-r4.zip if [ "$NEEDDIST" == "1" ]; then # Make source code archive which is architecture independent so it only needs to be done once diff --git a/contrib/gitian-descriptors/qt-linux.yml b/contrib/gitian-descriptors/qt-linux.yml index 1462df328..b163b4bb8 100644 --- a/contrib/gitian-descriptors/qt-linux.yml +++ b/contrib/gitian-descriptors/qt-linux.yml @@ -40,6 +40,7 @@ script: | tar xzf qt-everywhere-opensource-src-4.6.4.tar.gz cd qt-everywhere-opensource-src-4.6.4 QTBUILDDIR=$(pwd) + sed 's/TODAY=`date +%Y-%m-%d`/TODAY=2011-01-30/' -i configure # Need to build 4.6-versioned host utilities as well (lrelease/qrc/lupdate/...) ./configure -prefix $INSTALLPREFIX -confirm-license -release -opensource -no-qt3support -no-multimedia -no-audio-backend -no-phonon -no-phonon-backend -no-declarative -no-script -no-scripttools -no-javascript-jit -no-webkit -no-svg -no-xmlpatterns -no-sql-sqlite -no-nis -no-cups -no-iconv -no-dbus -no-gif -no-libtiff -no-opengl -nomake examples -nomake demos -nomake docs diff --git a/contrib/gitian-descriptors/qt-win.yml b/contrib/gitian-descriptors/qt-win.yml index 9dbe90259..eba6f3413 100644 --- a/contrib/gitian-descriptors/qt-win.yml +++ b/contrib/gitian-descriptors/qt-win.yml @@ -15,8 +15,8 @@ reference_datetime: "2011-01-30 00:00:00" remotes: [] files: - "qt-everywhere-opensource-src-5.2.0.tar.gz" -- "dogecoin-deps-win32-gitian-r12.zip" -- "dogecoin-deps-win64-gitian-r12.zip" +- "dogecoin-deps-win32-gitian-r13.zip" +- "dogecoin-deps-win64-gitian-r13.zip" script: | # Defines export TZ=UTC @@ -48,7 +48,7 @@ script: | # # Need mingw-compiled openssl from dogecoin-deps: cd $DEPSDIR - unzip $INDIR/dogecoin-deps-win${BITS}-gitian-r12.zip + unzip $INDIR/dogecoin-deps-win${BITS}-gitian-r13.zip # cd $BUILDDIR # diff --git a/doc/release-notes.md b/doc/release-notes.md index dab87ebda..bd76f4499 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -1,53 +1,35 @@ -Bitcoin Core version 0.9.0rc3 is now available from: +Bitcoin Core version 0.9.2 is now available from: - https://bitcoin.org/bin/0.9.0/test/ + https://bitcoin.org/bin/0.9.2/ -This is a release candidate for a new major version. A major version brings -both new features and bug fixes. +This is a new minor version release, bringing mostly bug fixes and some minor +improvements. OpenSSL has been updated because of a security issue (CVE-2014-0224). +Upgrading to this release is recommended. Please report bugs using the issue tracker at github: https://github.com/bitcoin/bitcoin/issues +Upgrading and downgrading +========================== + How to Upgrade -------------- If you are running an older version, shut it down. Wait until it has completely -shut down (which might take a few minutes for older versions), uninstall all -earlier versions of Bitcoin, then run the installer (on Windows) or just copy -over /Applications/Bitcoin-Qt (on Mac) or bitcoind/bitcoin-qt (on Linux). +shut down (which might take a few minutes for older versions), then run the +installer (on Windows) or just copy over /Applications/Bitcoin-Qt (on Mac) or +bitcoind/bitcoin-qt (on Linux). If you are upgrading from version 0.7.2 or earlier, the first time you run 0.9.0 your blockchain files will be re-indexed, which will take anywhere from 30 minutes to several hours, depending on the speed of your machine. -On Windows, do not forget to uninstall all earlier versions of the Bitcoin -client first, especially if you are switching to the 64-bit version. - -Windows 64-bit installer -------------------------- - -New in 0.9.0 is the Windows 64-bit version of the client. There have been -frequent reports of users running out of virtual memory on 32-bit systems -during the initial sync. Because of this it is recommended to install the -64-bit version if your system supports it. - -NOTE: Release candidate 2 Windows binaries are not code-signed; use PGP -and the SHA256SUMS.asc file to make sure your binaries are correct. -In the final 0.9.0 release, Windows setup.exe binaries will be code-signed. - -OSX 10.5 / 32-bit no longer supported -------------------------------------- - -0.9.0 drops support for older Macs. The minimum requirements are now: -* A 64-bit-capable CPU (see http://support.apple.com/kb/ht3696); -* Mac OS 10.6 or later (see https://support.apple.com/kb/ht1633). - Downgrading warnings -------------------- The 'chainstate' for this release is not always compatible with previous -releases, so if you run 0.9 and then decide to switch back to a +releases, so if you run 0.9.x and then decide to switch back to a 0.8.x release you might get a blockchain validation error when starting the old release (due to 'pruned outputs' being omitted from the index of unspent transaction outputs). @@ -59,339 +41,164 @@ Also, the first time you run a 0.8.x release on a 0.9 wallet it will rescan the blockchain for missing spent coins, which will take a long time (tens of minutes on a typical machine). -Rebranding to Bitcoin Core ---------------------------- +Important changes +================== -To reduce confusion between Bitcoin-the-network and Bitcoin-the-software we -have renamed the reference client to Bitcoin Core. +Gitian OSX build +----------------- -Autotools build system ------------------------ +The deterministic build system that was already used for Windows and Linux +builds is now used for OSX as well. Although the resulting executables have +been tested quite a bit, there could be possible regressions. Be sure to report +these on the Github bug tracker mentioned above. -For 0.9.0 we switched to an autotools-based build system instead of individual -(q)makefiles. +Compatibility of Linux build +----------------------------- -Using the standard "./autogen.sh; ./configure; make" to build Bitcoin-Qt and -bitcoind makes it easier for experienced open source developers to contribute -to the project. +For Linux we now build against Qt 4.6, and filter the symbols for libstdc++ and glibc. +This brings back compatibility with -Be sure to check doc/build-*.md for your platform before building from source. +- Debian 6+ / Tails +- Ubuntu 10.04 +- CentOS 6.5 -Bitcoin-cli -------------- - -Another change in the 0.9 release is moving away from the bitcoind executable -functioning both as a server and as a RPC client. The RPC client functionality -("tell the running bitcoin daemon to do THIS") was split into a separate -executable, 'bitcoin-cli'. The RPC client code will eventually be removed from -bitcoind, but will be kept for backwards compatibility for a release or two. - -`walletpassphrase` RPC ------------------------ - -The behavior of the `walletpassphrase` RPC when the wallet is already unlocked -has changed between 0.8 and 0.9. - -The 0.8 behavior of `walletpassphrase` is to fail when the wallet is already unlocked: - - > walletpassphrase 1000 - walletunlocktime = now + 1000 - > walletpassphrase 10 - Error: Wallet is already unlocked (old unlock time stays) - -The new behavior of `walletpassphrase` is to set a new unlock time overriding -the old one: - - > walletpassphrase 1000 - walletunlocktime = now + 1000 - > walletpassphrase 10 - walletunlocktime = now + 10 (overriding the old unlock time) - -Transaction malleability-related fixes --------------------------------------- - -This release contains a few fixes for transaction ID (TXID) malleability -issues: - -- -spendzeroconfchange=0 command-line option, to avoid spending - zero-confirmation change -- IsStandard() transaction rules tightened to prevent relaying and mining of - mutated transactions -- Additional information in listtransactions/gettransaction output to - report wallet transactions that conflict with each other because - they spend the same outputs. -- Bug fixes to the getbalance/listaccounts RPC commands, which would report - incorrect balances for double-spent (or mutated) transactions. -- New option: -zapwallettxes to rebuild the wallet's transaction information - -Transaction Fees ----------------- - -This release drops the default fee required to relay transactions across the -network and for miners to consider the transaction in their blocks to -0.01mBTC per kilobyte. - -Note that getting a transaction relayed across the network does NOT guarantee -that the transaction will be accepted by a miner; by default, miners fill -their blocks with 50 kilobytes of high-priority transactions, and then with -700 kilobytes of the highest-fee-per-kilobyte transactions. - -The minimum relay/mining fee-per-kilobyte may be changed with the -minrelaytxfee option. Note that previous releases incorrectly used -the mintxfee setting to determine which low-priority transactions should -be considered for inclusion in blocks. - -The wallet code still uses a default fee for low-priority transactions of -0.1mBTC per kilobyte. During periods of heavy transaction volume, even this -fee may not be enough to get transactions confirmed quickly; the mintxfee -option may be used to override the default. - -0.9.0rc3 Release notes +0.9.2 Release notes ======================= -RPC: +The OpenSSL dependency in the gitian builds has been upgraded to 1.0.1h because of CVE-2014-0224. -- New notion of 'conflicted' transactions, reported as confirmations: -1 -- 'listreceivedbyaddress' now provides tx ids -- Add raw transaction hex to 'gettransaction' output -- Updated help and tests for 'getreceivedby(account|address)' -- In 'getblock', accept 2nd 'verbose' parameter, similar to getrawtransaction, - but defaulting to 1 for backward compatibility -- Add 'verifychain', to verify chain database at runtime -- Add 'dumpwallet' and 'importwallet' RPCs -- 'keypoolrefill' gains optional size parameter -- Add 'getbestblockhash', to return tip of best chain -- Add 'chainwork' (the total work done by all blocks since the genesis block) - to 'getblock' output -- Make RPC password resistant to timing attacks -- Clarify help messages and add examples -- Add 'getrawchangeaddress' call for raw transaction change destinations -- Reject insanely high fees by default in 'sendrawtransaction' -- Add RPC call 'decodescript' to decode a hex-encoded transaction script -- Make 'validateaddress' provide redeemScript -- Add 'getnetworkhashps' to get the calculated network hashrate -- New RPC 'ping' command to request ping, new 'pingtime' and 'pingwait' fields - in 'getpeerinfo' output -- Adding new 'addrlocal' field to 'getpeerinfo' output -- Add verbose boolean to 'getrawmempool' -- Add rpc command 'getunconfirmedbalance' to obtain total unconfirmed balance -- Explicitly ensure that wallet is unlocked in `importprivkey` -- Add check for valid keys in `importprivkey` +RPC: +- Add `getwalletinfo`, `getblockchaininfo` and `getnetworkinfo` calls (will replace hodge-podge `getinfo` at some point) +- Add a `relayfee` field to `getnetworkinfo` +- Fix RPC related shutdown hangs and leaks +- Always show syncnode in `getpeerinfo` +- `sendrawtransaction`: report the reject code and reason, and make it possible to re-send transactions that are already in the mempool +- `getmininginfo` show right genproclimit Command-line options: - -- New option: -nospendzeroconfchange to never spend unconfirmed change outputs -- New option: -zapwallettxes to rebuild the wallet's transaction information -- Rename option '-tor' to '-onion' to better reflect what it does -- Add '-disablewallet' mode to let bitcoind run entirely without wallet (when - built with wallet) -- Update default '-rpcsslciphers' to include TLSv1.2 -- make '-logtimestamps' default on and rework help-message -- RPC client option: '-rpcwait', to wait for server start -- Remove '-logtodebugger' -- Allow `-noserver` with bitcoind +- Fix `-printblocktree` output +- Show error message if ReadConfigFile fails Block-chain handling and storage: +- Fix for GetBlockValue() after block 13,440,000 (BIP42) +- Upgrade leveldb to 1.17 -- Update leveldb to 1.15 -- Check for correct genesis (prevent cases where a datadir from the wrong - network is accidentally loaded) -- Allow txindex to be removed and add a reindex dialog -- Log aborted block database rebuilds -- Store orphan blocks in serialized form, to save memory -- Limit the number of orphan blocks in memory to 750 -- Fix non-standard disconnected transactions causing mempool orphans -- Add a new checkpoint at block 279,000 +Protocol and network code: +- Per-peer block download tracking and stalled download detection +- Add new DNS seed from bitnodes.io +- Prevent socket leak in ThreadSocketHandler and correct some proxy related socket leaks +- Use pnode->nLastRecv as sync score (was the wrong way around) Wallet: - -- Bug fixes and new regression tests to correctly compute - the balance of wallets containing double-spent (or mutated) transactions -- Store key creation time. Calculate whole-wallet birthday. -- Optimize rescan to skip blocks prior to birthday -- Let user select wallet file with -wallet=foo.dat -- Consider generated coins mature at 101 instead of 120 blocks -- Improve wallet load time -- Don't count txins for priority to encourage sweeping -- Don't create empty transactions when reading a corrupted wallet -- Fix rescan to start from beginning after importprivkey -- Only create signatures with low S values - -Mining: - -- Increase default -blockmaxsize/prioritysize to 750K/50K -- 'getblocktemplate' does not require a key to create a block template -- Mining code fee policy now matches relay fee policy - -Protocol and network: - -- Drop the fee required to relay a transaction to 0.01mBTC per kilobyte -- Send tx relay flag with version -- New 'reject' P2P message (BIP 0061, see - https://gist.github.com/gavinandresen/7079034 for draft) -- Dump addresses every 15 minutes instead of 10 seconds -- Relay OP_RETURN data TxOut as standard transaction type -- Remove CENT-output free transaction rule when relaying -- Lower maximum size for free transaction creation -- Send multiple inv messages if mempool.size > MAX_INV_SZ -- Split MIN_PROTO_VERSION into INIT_PROTO_VERSION and MIN_PEER_PROTO_VERSION -- Do not treat fFromMe transaction differently when broadcasting -- Process received messages one at a time without sleeping between messages -- Improve logging of failed connections -- Bump protocol version to 70002 -- Add some additional logging to give extra network insight -- Added new DNS seed from bitcoinstats.com - -Validation: - -- Log reason for non-standard transaction rejection -- Prune provably-unspendable outputs, and adapt consistency check for it. -- Detect any sufficiently long fork and add a warning -- Call the -alertnotify script when we see a long or invalid fork -- Fix multi-block reorg transaction resurrection -- Reject non-canonically-encoded serialization sizes -- Reject dust amounts during validation -- Accept nLockTime transactions that finalize in the next block +- Make GetAvailableCredit run GetHash() only once per transaction (performance improvement) +- Lower paytxfee warning threshold from 0.25 BTC to 0.01 BTC +- Fix importwallet nTimeFirstKey (trigger necessary rescans) +- Log BerkeleyDB version at startup +- CWallet init fix Build system: - -- Switch to autotools-based build system -- Build without wallet by passing `--disable-wallet` to configure, this - removes the BerkeleyDB dependency -- Upgrade gitian dependencies (libpng, libz, libupnpc, boost, openssl) to more - recent versions -- Windows 64-bit build support -- Solaris compatibility fixes -- Check integrity of gitian input source tarballs -- Enable full GCC Stack-smashing protection for all OSes +- Add OSX build descriptors to gitian +- Fix explicit --disable-qt-dbus +- Don't require db_cxx.h when compiling with wallet disabled and GUI enabled +- Improve missing boost error reporting +- Upgrade miniupnpc version to 1.9 +- gitian-linux: --enable-glibc-back-compat for binary compatibility with old distributions +- gitian: don't export any symbols from executable +- gitian: build against Qt 4.6 +- devtools: add script to check symbols from Linux gitian executables +- Remove build-time no-IPv6 setting GUI: - -- Switch to Qt 5.2.0 for Windows build -- Add payment request (BIP 0070) support -- Improve options dialog -- Show transaction fee in new send confirmation dialog -- Add total balance in overview page -- Allow user to choose data directory on first start, when data directory is - missing, or when the -choosedatadir option is passed -- Save and restore window positions -- Add vout index to transaction id in transactions details dialog -- Add network traffic graph in debug window -- Add open URI dialog -- Add Coin Control Features -- Improve receive coins workflow: make the 'Receive' tab into a form to request - payments, and move historical address list functionality to File menu. -- Rebrand to `Bitcoin Core` -- Move initialization/shutdown to a thread. This prevents "Not responding" - messages during startup. Also show a window during shutdown. -- Don't regenerate autostart link on every client startup -- Show and store message of normal bitcoin:URI -- Fix richtext detection hang issue on very old Qt versions -- OS X: Make use of the 10.8+ user notification center to display Growl-like - notifications -- OS X: Added NSHighResolutionCapable flag to Info.plist for better font - rendering on Retina displays. -- OS X: Fix bitcoin-qt startup crash when clicking dock icon -- Linux: Fix Gnome bitcoin: URI handler +- Fix various coin control visual issues +- Show number of in/out connections in debug console +- Show weeks as well as years behind for long timespans behind +- Enable and disable the Show and Remove buttons for requested payments history based on whether any entry is selected. +- Show also value for options overridden on command line in options dialog +- Fill in label from address book also for URIs +- Fixes feel when resizing the last column on tables (issue #2862) +- Fix ESC in disablewallet mode +- Add expert section to wallet tab in optionsdialog +- Do proper boost::path conversion (fixes unicode in datadir) +- Only override -datadir if different from the default (fixes -datadir in config file) +- Show rescan progress at start-up +- Show importwallet progress +- Get required locks upfront in polling functions (avoids hanging on locks) +- Catch Windows shutdown events while client is running +- Optionally add third party links to transaction context menu +- Check for !pixmap() before trying to export QR code (avoids crashes when no QR code could be generated) +- Fix "Start bitcoin on system login" Miscellaneous: -- Add Linux script (contrib/qos/tc.sh) to limit outgoing bandwidth -- Add '-regtest' mode, similar to testnet but private with instant block - generation with 'setgenerate' RPC. -- Add 'linearize.py' script to contrib, for creating bootstrap.dat -- Add separate bitcoin-cli client +- Replace non-threadsafe C functions (gmtime, strerror and setlocale) +- Add missing cs_main and wallet locks +- Avoid exception at startup when system locale not recognized +- Changed bitrpc.py's raw_input to getpass for passwords to conceal characters during command line input +- devtools: add a script to fetch and postprocess translations Credits -------- Thanks to everyone who contributed to this release: -- Andrey -- Ashley Holman -- b6393ce9-d324-4fe1-996b-acf82dbc3d53 -- bitsofproof +- Addy Yeow +- Altoidnerd +- Andrea D'Amore +- Andreas Schildbach +- Bardi Harborow - Brandon Dahler -- Calvin Tam -- Christian Decker +- Bryan Bishop +- Chris Beams - Christian von Roques -- Christopher Latham -- Chuck -- coblee -- constantined - Cory Fields - Cozz Lovan - daniel -- Daniel Larimer -- David Hill -- Dmitry Smirnov -- Drak -- Eric Lombrozo -- fanquake -- fcicq -- Florin -- frewil +- Daniel Newton +- David A. Harding +- ditto-b +- duanemoody +- Eric S. Bullington +- Fabian Raetz - Gavin Andresen - Gregory Maxwell - gubatron -- Guillermo Céspedes Tabárez - Haakon Nilsen -- HaltingState -- Han Lin Yap - harry -- Ian Kelling +- Hector Jusforgues +- Isidoro Ghezzi - Jeff Garzik - Johnathan Corgan -- Jonas Schnelli -- Josh Lehan -- Josh Triplett -- Julian Langschaedel -- Kangmo -- Lake Denman +- jtimon +- Kamil Domanski +- langerhans - Luke Dashjr +- Manuel Araoz - Mark Friedenbach - Matt Corallo -- Michael Bauer +- Matthew Bogosian +- Meeh - Michael Ford - Michagogo -- Midnight Magic +- Mikael Wikman - Mike Hearn -- Nils Schneider -- Noel Tiernan -- Olivier Langlois -- patrick s -- Patrick Strateman +- olalonde - paveljanik -- Peter Todd -- phantomcircuit -- phelixbtc +- peryaudo - Philip Kaufmann +- philsong - Pieter Wuille -- Rav3nPL - R E Broadley -- regergregregerrge -- Robert Backhaus -- Roman Mindalev +- richierichrawr - Rune K. Svendsen -- Ryan Niebur -- Scott Ellis -- Scott Willeke -- Sergey Kazenyuk -- Shawn Wilkinson -- Sined -- sje -- Subo1978 +- rxl +- shshshsh +- Simon de la Rouviere +- Stuart Cardall - super3 -- Tamas Blummer -- theuni -- Thomas Holenstein -- Timon Rapp -- Timothy Stranex -- Tom Geller +- Telepatheic +- Thomas Zander - Torstein Husebø -- Vaclav Vobornik -- vhf / victor felder -- Vinnie Falco - Warren Togami -- Wil Bown - Wladimir J. van der Laan +- Yoichi Hirai + diff --git a/doc/release-process.md b/doc/release-process.md index 71ebca252..e71546522 100644 --- a/doc/release-process.md +++ b/doc/release-process.md @@ -38,7 +38,7 @@ Release Process mkdir -p inputs; cd inputs/ wget 'http://miniupnp.free.fr/files/download.php?file=miniupnpc-1.9.tar.gz' -O miniupnpc-1.9.tar.gz - wget 'https://www.openssl.org/source/openssl-1.0.1g.tar.gz' + wget 'https://www.openssl.org/source/openssl-1.0.1h.tar.gz' wget 'http://download.oracle.com/berkeley-db/db-5.1.29.NC.tar.gz' wget 'http://zlib.net/zlib-1.2.8.tar.gz' wget 'ftp://ftp.simplesystems.org/pub/png/src/history/libpng16/libpng-1.6.8.tar.gz' @@ -67,16 +67,16 @@ Release Process The expected SHA256 hashes of the intermediate inputs are: - 2bde8b4711c763f6a51449ce814d51553650d88603eda0f85a1a2e95e97d83d0 dogecoin-deps-linux32-gitian-r5.zip - f88ca2b78e660622d58ea6cfb524427d6eedb82313124d8b80a48a8211a82dbb dogecoin-deps-linux64-gitian-r5.zip + 46710f673467e367738d8806e45b4cb5931aaeea61f4b6b55a68eea56d5006c5 dogecoin-deps-linux32-gitian-r6.zip + f03be39fb26670243d3a659e64d18e19d03dec5c11e9912011107768390b5268 dogecoin-deps-linux64-gitian-r6.zip f29b7d9577417333fb56e023c2977f5726a7c297f320b175a4108cf7cd4c2d29 boost-linux32-1.55.0-gitian-r1.zip 88232451c4104f7eb16e469ac6474fd1231bd485687253f7b2bdf46c0781d535 boost-linux64-1.55.0-gitian-r1.zip - 74ec2d301cf1a9d03b194153f545102ba45dad02b390485212fe6717de486361 qt-linux32-4.6.4-gitian-r1.tar.gz - 01d0477e299467f09280f15424781154e2b1ea4072c5edb16e044c234954fd9a qt-linux64-4.6.4-gitian-r1.tar.gz + 57e57dbdadc818cd270e7e00500a5e1085b3bcbdef69a885f0fb7573a8d987e1 qt-linux32-4.6.4-gitian-r1.tar.gz + 60eb4b9c5779580b7d66529efa5b2836ba1a70edde2a0f3f696d647906a826be qt-linux64-4.6.4-gitian-r1.tar.gz 60dc2d3b61e9c7d5dbe2f90d5955772ad748a47918ff2d8b74e8db9b1b91c909 boost-win32-1.55.0-gitian-r6.zip f65fcaf346bc7b73bc8db3a8614f4f6bee2f61fcbe495e9881133a7c2612a167 boost-win64-1.55.0-gitian-r6.zip - b16bc26125f824f38e42b5f76c1134ccd10c1497238943d5e445d10f2d88733f dogecoin-deps-win32-gitian-r12.zip - 701bcb0938f86f8a3a2c2f26e7d680ad1678ade57b2cbae20888cddde4539acf dogecoin-deps-win64-gitian-r12.zip + 70de248cd0dd7e7476194129e818402e974ca9c5751cbf591644dc9f332d3b59 dogecoin-deps-win32-gitian-r13.zip + 9eace4c76f639f4f3580a478eee4f50246e1bbb5ccdcf37a158261a5a3fa3e65 dogecoin-deps-win64-gitian-r13.zip 963e3e5e85879010a91143c90a711a5d1d5aba992e38672cdf7b54e42c56b2f1 qt-win32-5.2.0-gitian-r3.zip 751c579830d173ef3e6f194e83d18b92ebef6df03289db13ab77a52b6bc86ef0 qt-win64-5.2.0-gitian-r3.zip e2e403e1a08869c7eed4d4293bce13d51ec6a63592918b90ae215a0eceb44cb4 protobuf-win32-2.5.0-gitian-r4.zip diff --git a/src/base58.cpp b/src/base58.cpp index 0b08ee3d0..597570388 100644 --- a/src/base58.cpp +++ b/src/base58.cpp @@ -2,11 +2,18 @@ // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include "base58.h" + +#include "hash.h" +#include "uint256.h" + #include #include #include #include #include +#include +#include /* All alphanumeric characters except for "0", "I", "O", and "l" */ static const char* pszBase58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; @@ -89,3 +96,179 @@ std::string EncodeBase58(const unsigned char* pbegin, const unsigned char* pend) str += pszBase58[*(it++)]; return str; } + +std::string EncodeBase58(const std::vector& vch) { + return EncodeBase58(&vch[0], &vch[0] + vch.size()); +} + +bool DecodeBase58(const std::string& str, std::vector& vchRet) { + return DecodeBase58(str.c_str(), vchRet); +} + +std::string EncodeBase58Check(const std::vector& vchIn) { + // add 4-byte hash check to the end + std::vector vch(vchIn); + uint256 hash = Hash(vch.begin(), vch.end()); + vch.insert(vch.end(), (unsigned char*)&hash, (unsigned char*)&hash + 4); + return EncodeBase58(vch); +} + +bool DecodeBase58Check(const char* psz, std::vector& vchRet) { + if (!DecodeBase58(psz, vchRet)) + return false; + if (vchRet.size() < 4) + { + vchRet.clear(); + return false; + } + // re-calculate the checksum, insure it matches the included 4-byte checksum + uint256 hash = Hash(vchRet.begin(), vchRet.end()-4); + if (memcmp(&hash, &vchRet.end()[-4], 4) != 0) + { + vchRet.clear(); + return false; + } + vchRet.resize(vchRet.size()-4); + return true; +} + +bool DecodeBase58Check(const std::string& str, std::vector& vchRet) { + return DecodeBase58Check(str.c_str(), vchRet); +} + +CBase58Data::CBase58Data() { + vchVersion.clear(); + vchData.clear(); +} + +void CBase58Data::SetData(const std::vector &vchVersionIn, const void* pdata, size_t nSize) { + vchVersion = vchVersionIn; + vchData.resize(nSize); + if (!vchData.empty()) + memcpy(&vchData[0], pdata, nSize); +} + +void CBase58Data::SetData(const std::vector &vchVersionIn, const unsigned char *pbegin, const unsigned char *pend) { + SetData(vchVersionIn, (void*)pbegin, pend - pbegin); +} + +bool CBase58Data::SetString(const char* psz, unsigned int nVersionBytes) { + std::vector vchTemp; + DecodeBase58Check(psz, vchTemp); + if (vchTemp.size() < nVersionBytes) { + vchData.clear(); + vchVersion.clear(); + return false; + } + vchVersion.assign(vchTemp.begin(), vchTemp.begin() + nVersionBytes); + vchData.resize(vchTemp.size() - nVersionBytes); + if (!vchData.empty()) + memcpy(&vchData[0], &vchTemp[nVersionBytes], vchData.size()); + OPENSSL_cleanse(&vchTemp[0], vchData.size()); + return true; +} + +bool CBase58Data::SetString(const std::string& str) { + return SetString(str.c_str()); +} + +std::string CBase58Data::ToString() const { + std::vector vch = vchVersion; + vch.insert(vch.end(), vchData.begin(), vchData.end()); + return EncodeBase58Check(vch); +} + +int CBase58Data::CompareTo(const CBase58Data& b58) const { + if (vchVersion < b58.vchVersion) return -1; + if (vchVersion > b58.vchVersion) return 1; + if (vchData < b58.vchData) return -1; + if (vchData > b58.vchData) return 1; + return 0; +} + +namespace { + class CBitcoinAddressVisitor : public boost::static_visitor { + private: + CBitcoinAddress *addr; + public: + CBitcoinAddressVisitor(CBitcoinAddress *addrIn) : addr(addrIn) { } + + bool operator()(const CKeyID &id) const { return addr->Set(id); } + bool operator()(const CScriptID &id) const { return addr->Set(id); } + bool operator()(const CNoDestination &no) const { return false; } + }; +}; + +bool CBitcoinAddress::Set(const CKeyID &id) { + SetData(Params().Base58Prefix(CChainParams::PUBKEY_ADDRESS), &id, 20); + return true; +} + +bool CBitcoinAddress::Set(const CScriptID &id) { + SetData(Params().Base58Prefix(CChainParams::SCRIPT_ADDRESS), &id, 20); + return true; +} + +bool CBitcoinAddress::Set(const CTxDestination &dest) { + return boost::apply_visitor(CBitcoinAddressVisitor(this), dest); +} + +bool CBitcoinAddress::IsValid() const { + bool fCorrectSize = vchData.size() == 20; + bool fKnownVersion = vchVersion == Params().Base58Prefix(CChainParams::PUBKEY_ADDRESS) || + vchVersion == Params().Base58Prefix(CChainParams::SCRIPT_ADDRESS); + return fCorrectSize && fKnownVersion; +} + +CTxDestination CBitcoinAddress::Get() const { + if (!IsValid()) + return CNoDestination(); + uint160 id; + memcpy(&id, &vchData[0], 20); + if (vchVersion == Params().Base58Prefix(CChainParams::PUBKEY_ADDRESS)) + return CKeyID(id); + else if (vchVersion == Params().Base58Prefix(CChainParams::SCRIPT_ADDRESS)) + return CScriptID(id); + else + return CNoDestination(); +} + +bool CBitcoinAddress::GetKeyID(CKeyID &keyID) const { + if (!IsValid() || vchVersion != Params().Base58Prefix(CChainParams::PUBKEY_ADDRESS)) + return false; + uint160 id; + memcpy(&id, &vchData[0], 20); + keyID = CKeyID(id); + return true; +} + +bool CBitcoinAddress::IsScript() const { + return IsValid() && vchVersion == Params().Base58Prefix(CChainParams::SCRIPT_ADDRESS); +} + +void CBitcoinSecret::SetKey(const CKey& vchSecret) { + assert(vchSecret.IsValid()); + SetData(Params().Base58Prefix(CChainParams::SECRET_KEY), vchSecret.begin(), vchSecret.size()); + if (vchSecret.IsCompressed()) + vchData.push_back(1); +} + +CKey CBitcoinSecret::GetKey() { + CKey ret; + ret.Set(&vchData[0], &vchData[32], vchData.size() > 32 && vchData[32] == 1); + return ret; +} + +bool CBitcoinSecret::IsValid() const { + bool fExpectedFormat = vchData.size() == 32 || (vchData.size() == 33 && vchData[32] == 1); + bool fCorrectVersion = vchVersion == Params().Base58Prefix(CChainParams::SECRET_KEY); + return fExpectedFormat && fCorrectVersion; +} + +bool CBitcoinSecret::SetString(const char* pszSecret) { + return CBase58Data::SetString(pszSecret) && IsValid(); +} + +bool CBitcoinSecret::SetString(const std::string& strSecret) { + return SetString(strSecret.c_str()); +} diff --git a/src/base58.h b/src/base58.h index 4fb436c5e..70681f589 100644 --- a/src/base58.h +++ b/src/base58.h @@ -15,17 +15,12 @@ #define BITCOIN_BASE58_H #include "chainparams.h" -#include "hash.h" #include "key.h" #include "script.h" -#include "uint256.h" #include #include -#include -#include - /** * Encode a byte sequence as a base58-encoded string. * pbegin and pend cannot be NULL, unless both are. @@ -35,10 +30,7 @@ std::string EncodeBase58(const unsigned char* pbegin, const unsigned char* pend) /** * Encode a byte vector as a base58-encoded string */ -inline std::string EncodeBase58(const std::vector& vch) -{ - return EncodeBase58(&vch[0], &vch[0] + vch.size()); -} +std::string EncodeBase58(const std::vector& vch); /** * Decode a base58-encoded string (psz) into a byte vector (vchRet). @@ -51,55 +43,24 @@ bool DecodeBase58(const char* psz, std::vector& vchRet); * Decode a base58-encoded string (str) into a byte vector (vchRet). * return true if decoding is successful. */ -inline bool DecodeBase58(const std::string& str, std::vector& vchRet) -{ - return DecodeBase58(str.c_str(), vchRet); -} +bool DecodeBase58(const std::string& str, std::vector& vchRet); /** * Encode a byte vector into a base58-encoded string, including checksum */ -inline std::string EncodeBase58Check(const std::vector& vchIn) -{ - // add 4-byte hash check to the end - std::vector vch(vchIn); - uint256 hash = Hash(vch.begin(), vch.end()); - vch.insert(vch.end(), (unsigned char*)&hash, (unsigned char*)&hash + 4); - return EncodeBase58(vch); -} +std::string EncodeBase58Check(const std::vector& vchIn); /** * Decode a base58-encoded string (psz) that includes a checksum into a byte * vector (vchRet), return true if decoding is successful */ -inline bool DecodeBase58Check(const char* psz, std::vector& vchRet) -{ - if (!DecodeBase58(psz, vchRet)) - return false; - if (vchRet.size() < 4) - { - vchRet.clear(); - return false; - } - // re-calculate the checksum, insure it matches the included 4-byte checksum - uint256 hash = Hash(vchRet.begin(), vchRet.end()-4); - if (memcmp(&hash, &vchRet.end()[-4], 4) != 0) - { - vchRet.clear(); - return false; - } - vchRet.resize(vchRet.size()-4); - return true; -} +inline bool DecodeBase58Check(const char* psz, std::vector& vchRet); /** * Decode a base58-encoded string (str) that includes a checksum into a byte * vector (vchRet), return true if decoding is successful */ -inline bool DecodeBase58Check(const std::string& str, std::vector& vchRet) -{ - return DecodeBase58Check(str.c_str(), vchRet); -} +inline bool DecodeBase58Check(const std::string& str, std::vector& vchRet); /** * Base class for all base58-encoded data @@ -114,64 +75,15 @@ protected: typedef std::vector > vector_uchar; vector_uchar vchData; - CBase58Data() - { - vchVersion.clear(); - vchData.clear(); - } - - void SetData(const std::vector &vchVersionIn, const void* pdata, size_t nSize) - { - vchVersion = vchVersionIn; - vchData.resize(nSize); - if (!vchData.empty()) - memcpy(&vchData[0], pdata, nSize); - } - - void SetData(const std::vector &vchVersionIn, const unsigned char *pbegin, const unsigned char *pend) - { - SetData(vchVersionIn, (void*)pbegin, pend - pbegin); - } + CBase58Data(); + void SetData(const std::vector &vchVersionIn, const void* pdata, size_t nSize); + void SetData(const std::vector &vchVersionIn, const unsigned char *pbegin, const unsigned char *pend); public: - bool SetString(const char* psz, unsigned int nVersionBytes = 1) - { - std::vector vchTemp; - DecodeBase58Check(psz, vchTemp); - if (vchTemp.size() < nVersionBytes) - { - vchData.clear(); - vchVersion.clear(); - return false; - } - vchVersion.assign(vchTemp.begin(), vchTemp.begin() + nVersionBytes); - vchData.resize(vchTemp.size() - nVersionBytes); - if (!vchData.empty()) - memcpy(&vchData[0], &vchTemp[nVersionBytes], vchData.size()); - OPENSSL_cleanse(&vchTemp[0], vchData.size()); - return true; - } - - bool SetString(const std::string& str) - { - return SetString(str.c_str()); - } - - std::string ToString() const - { - std::vector vch = vchVersion; - vch.insert(vch.end(), vchData.begin(), vchData.end()); - return EncodeBase58Check(vch); - } - - int CompareTo(const CBase58Data& b58) const - { - if (vchVersion < b58.vchVersion) return -1; - if (vchVersion > b58.vchVersion) return 1; - if (vchData < b58.vchData) return -1; - if (vchData > b58.vchData) return 1; - return 0; - } + bool SetString(const char* psz, unsigned int nVersionBytes = 1); + bool SetString(const std::string& str); + std::string ToString() const; + int CompareTo(const CBase58Data& b58) const; bool operator==(const CBase58Data& b58) const { return CompareTo(b58) == 0; } bool operator<=(const CBase58Data& b58) const { return CompareTo(b58) <= 0; } @@ -186,140 +98,37 @@ public: * Script-hash-addresses have version 5 (or 196 testnet). * The data vector contains RIPEMD160(SHA256(cscript)), where cscript is the serialized redemption script. */ -class CBitcoinAddress; -class CBitcoinAddressVisitor : public boost::static_visitor -{ -private: - CBitcoinAddress *addr; +class CBitcoinAddress : public CBase58Data { public: - CBitcoinAddressVisitor(CBitcoinAddress *addrIn) : addr(addrIn) { } - bool operator()(const CKeyID &id) const; - bool operator()(const CScriptID &id) const; - bool operator()(const CNoDestination &no) const; + bool Set(const CKeyID &id); + bool Set(const CScriptID &id); + bool Set(const CTxDestination &dest); + bool IsValid() const; + + CBitcoinAddress() {} + CBitcoinAddress(const CTxDestination &dest) { Set(dest); } + CBitcoinAddress(const std::string& strAddress) { SetString(strAddress); } + CBitcoinAddress(const char* pszAddress) { SetString(pszAddress); } + + CTxDestination Get() const; + bool GetKeyID(CKeyID &keyID) const; + bool IsScript() const; }; -class CBitcoinAddress : public CBase58Data -{ -public: - bool Set(const CKeyID &id) { - SetData(Params().Base58Prefix(CChainParams::PUBKEY_ADDRESS), &id, 20); - return true; - } - - bool Set(const CScriptID &id) { - SetData(Params().Base58Prefix(CChainParams::SCRIPT_ADDRESS), &id, 20); - return true; - } - - bool Set(const CTxDestination &dest) - { - return boost::apply_visitor(CBitcoinAddressVisitor(this), dest); - } - - bool IsValid() const - { - bool fCorrectSize = vchData.size() == 20; - bool fKnownVersion = vchVersion == Params().Base58Prefix(CChainParams::PUBKEY_ADDRESS) || - vchVersion == Params().Base58Prefix(CChainParams::SCRIPT_ADDRESS); - return fCorrectSize && fKnownVersion; - } - - CBitcoinAddress() - { - } - - CBitcoinAddress(const CTxDestination &dest) - { - Set(dest); - } - - CBitcoinAddress(const std::string& strAddress) - { - SetString(strAddress); - } - - CBitcoinAddress(const char* pszAddress) - { - SetString(pszAddress); - } - - CTxDestination Get() const { - if (!IsValid()) - return CNoDestination(); - uint160 id; - memcpy(&id, &vchData[0], 20); - if (vchVersion == Params().Base58Prefix(CChainParams::PUBKEY_ADDRESS)) - return CKeyID(id); - else if (vchVersion == Params().Base58Prefix(CChainParams::SCRIPT_ADDRESS)) - return CScriptID(id); - else - return CNoDestination(); - } - - bool GetKeyID(CKeyID &keyID) const { - if (!IsValid() || vchVersion != Params().Base58Prefix(CChainParams::PUBKEY_ADDRESS)) - return false; - uint160 id; - memcpy(&id, &vchData[0], 20); - keyID = CKeyID(id); - return true; - } - - bool IsScript() const { - return IsValid() && vchVersion == Params().Base58Prefix(CChainParams::SCRIPT_ADDRESS); - } -}; - -bool inline CBitcoinAddressVisitor::operator()(const CKeyID &id) const { return addr->Set(id); } -bool inline CBitcoinAddressVisitor::operator()(const CScriptID &id) const { return addr->Set(id); } -bool inline CBitcoinAddressVisitor::operator()(const CNoDestination &id) const { return false; } - /** * A base58-encoded secret key */ class CBitcoinSecret : public CBase58Data { public: - void SetKey(const CKey& vchSecret) - { - assert(vchSecret.IsValid()); - SetData(Params().Base58Prefix(CChainParams::SECRET_KEY), vchSecret.begin(), vchSecret.size()); - if (vchSecret.IsCompressed()) - vchData.push_back(1); - } + void SetKey(const CKey& vchSecret); + CKey GetKey(); + bool IsValid() const; + bool SetString(const char* pszSecret); + bool SetString(const std::string& strSecret); - CKey GetKey() - { - CKey ret; - ret.Set(&vchData[0], &vchData[32], vchData.size() > 32 && vchData[32] == 1); - return ret; - } - - bool IsValid() const - { - bool fExpectedFormat = vchData.size() == 32 || (vchData.size() == 33 && vchData[32] == 1); - bool fCorrectVersion = vchVersion == Params().Base58Prefix(CChainParams::SECRET_KEY); - return fExpectedFormat && fCorrectVersion; - } - - bool SetString(const char* pszSecret) - { - return CBase58Data::SetString(pszSecret) && IsValid(); - } - - bool SetString(const std::string& strSecret) - { - return SetString(strSecret.c_str()); - } - - CBitcoinSecret(const CKey& vchSecret) - { - SetKey(vchSecret); - } - - CBitcoinSecret() - { - } + CBitcoinSecret(const CKey& vchSecret) { SetKey(vchSecret); } + CBitcoinSecret() {} }; template class CBitcoinExtKeyBase : public CBase58Data diff --git a/src/dogecoin-cli.cpp b/src/dogecoin-cli.cpp index 18c2b7212..84ea86cea 100644 --- a/src/dogecoin-cli.cpp +++ b/src/dogecoin-cli.cpp @@ -58,6 +58,8 @@ static bool AppInitRPC(int argc, char* argv[]) int main(int argc, char* argv[]) { + SetupEnvironment(); + try { if(!AppInitRPC(argc, argv)) diff --git a/src/dogecoind.cpp b/src/dogecoind.cpp index 9eee562d4..cfb3d8cb6 100644 --- a/src/dogecoind.cpp +++ b/src/dogecoind.cpp @@ -172,6 +172,8 @@ bool AppInit(int argc, char* argv[]) int main(int argc, char* argv[]) { + SetupEnvironment(); + bool fRet = false; // Connect dogecoind signal handlers diff --git a/src/json/json_spirit_reader_template.h b/src/json/json_spirit_reader_template.h index 4dec00e6c..46f5892f6 100644 --- a/src/json/json_spirit_reader_template.h +++ b/src/json/json_spirit_reader_template.h @@ -33,8 +33,8 @@ namespace json_spirit { - const spirit_namespace::int_parser < boost::int64_t > int64_p = spirit_namespace::int_parser < boost::int64_t >(); - const spirit_namespace::uint_parser< boost::uint64_t > uint64_p = spirit_namespace::uint_parser< boost::uint64_t >(); + const spirit_namespace::int_parser < int64_t > int64_p = spirit_namespace::int_parser < int64_t >(); + const spirit_namespace::uint_parser< uint64_t > uint64_p = spirit_namespace::uint_parser< uint64_t >(); template< class Iter_type > bool is_eq( Iter_type first, Iter_type last, const char* c_str ) @@ -270,12 +270,12 @@ namespace json_spirit add_to_current( Value_type() ); } - void new_int( boost::int64_t i ) + void new_int( int64_t i ) { add_to_current( i ); } - void new_uint64( boost::uint64_t ui ) + void new_uint64( uint64_t ui ) { add_to_current( ui ); } @@ -425,8 +425,8 @@ namespace json_spirit typedef boost::function< void( Char_type ) > Char_action; typedef boost::function< void( Iter_type, Iter_type ) > Str_action; typedef boost::function< void( double ) > Real_action; - typedef boost::function< void( boost::int64_t ) > Int_action; - typedef boost::function< void( boost::uint64_t ) > Uint64_action; + typedef boost::function< void( int64_t ) > Int_action; + typedef boost::function< void( uint64_t ) > Uint64_action; Char_action begin_obj ( boost::bind( &Semantic_actions_t::begin_obj, &self.actions_, _1 ) ); Char_action end_obj ( boost::bind( &Semantic_actions_t::end_obj, &self.actions_, _1 ) ); diff --git a/src/json/json_spirit_value.h b/src/json/json_spirit_value.h index 7e83a2a7e..13cc89210 100644 --- a/src/json/json_spirit_value.h +++ b/src/json/json_spirit_value.h @@ -16,8 +16,8 @@ #include #include #include +#include #include -#include #include #include @@ -45,8 +45,8 @@ namespace json_spirit Value_impl( const Array& value ); Value_impl( bool value ); Value_impl( int value ); - Value_impl( boost::int64_t value ); - Value_impl( boost::uint64_t value ); + Value_impl( int64_t value ); + Value_impl( uint64_t value ); Value_impl( double value ); Value_impl( const Value_impl& other ); @@ -65,8 +65,8 @@ namespace json_spirit const Array& get_array() const; bool get_bool() const; int get_int() const; - boost::int64_t get_int64() const; - boost::uint64_t get_uint64() const; + int64_t get_int64() const; + uint64_t get_uint64() const; double get_real() const; Object& get_obj(); @@ -83,7 +83,7 @@ namespace json_spirit typedef boost::variant< String_type, boost::recursive_wrapper< Object >, boost::recursive_wrapper< Array >, - bool, boost::int64_t, double > Variant; + bool, int64_t, double > Variant; Value_type type_; Variant v_; @@ -258,13 +258,13 @@ namespace json_spirit template< class Config > Value_impl< Config >::Value_impl( int value ) : type_( int_type ) - , v_( static_cast< boost::int64_t >( value ) ) + , v_( static_cast< int64_t >( value ) ) , is_uint64_( false ) { } template< class Config > - Value_impl< Config >::Value_impl( boost::int64_t value ) + Value_impl< Config >::Value_impl( int64_t value ) : type_( int_type ) , v_( value ) , is_uint64_( false ) @@ -272,9 +272,9 @@ namespace json_spirit } template< class Config > - Value_impl< Config >::Value_impl( boost::uint64_t value ) + Value_impl< Config >::Value_impl( uint64_t value ) : type_( int_type ) - , v_( static_cast< boost::int64_t >( value ) ) + , v_( static_cast< int64_t >( value ) ) , is_uint64_( true ) { } @@ -390,19 +390,19 @@ namespace json_spirit } template< class Config > - boost::int64_t Value_impl< Config >::get_int64() const + int64_t Value_impl< Config >::get_int64() const { check_type( int_type ); - return boost::get< boost::int64_t >( v_ ); + return boost::get< int64_t >( v_ ); } template< class Config > - boost::uint64_t Value_impl< Config >::get_uint64() const + uint64_t Value_impl< Config >::get_uint64() const { check_type( int_type ); - return static_cast< boost::uint64_t >( get_int64() ); + return static_cast< uint64_t >( get_int64() ); } template< class Config > @@ -481,13 +481,13 @@ namespace json_spirit } template< class Value > - boost::int64_t get_value( const Value& value, Type_to_type< boost::int64_t > ) + int64_t get_value( const Value& value, Type_to_type< int64_t > ) { return value.get_int64(); } template< class Value > - boost::uint64_t get_value( const Value& value, Type_to_type< boost::uint64_t > ) + uint64_t get_value( const Value& value, Type_to_type< uint64_t > ) { return value.get_uint64(); } diff --git a/src/main.cpp b/src/main.cpp index 3dcc0d070..cfab94e65 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3577,7 +3577,10 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) return true; } - State(pfrom->GetId())->nLastBlockProcess = GetTimeMicros(); + { + LOCK(cs_main); + State(pfrom->GetId())->nLastBlockProcess = GetTimeMicros(); + } diff --git a/src/mruset.h b/src/mruset.h index c36a0c8f3..c1c08b028 100644 --- a/src/mruset.h +++ b/src/mruset.h @@ -32,6 +32,7 @@ public: bool empty() const { return set.empty(); } iterator find(const key_type& k) const { return set.find(k); } size_type count(const key_type& k) const { return set.count(k); } + void clear() { set.clear(); queue.clear(); } bool inline friend operator==(const mruset& a, const mruset& b) { return a.set == b.set; } bool inline friend operator==(const mruset& a, const std::set& b) { return a.set == b; } bool inline friend operator<(const mruset& a, const mruset& b) { return a.set < b.set; } diff --git a/src/net.cpp b/src/net.cpp index bd11ddaa9..5f284e0e2 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -178,7 +178,7 @@ bool RecvLine(SOCKET hSocket, string& strLine) { // socket error int nErr = WSAGetLastError(); - LogPrint("net", "recv failed: %d\n", nErr); + LogPrint("net", "recv failed: %s\n", NetworkErrorString(nErr)); return false; } } @@ -489,10 +489,10 @@ CNode* ConnectNode(CAddress addrConnect, const char *pszDest) #ifdef WIN32 u_long nOne = 1; if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR) - LogPrintf("ConnectSocket() : ioctlsocket non-blocking setting failed, error %d\n", WSAGetLastError()); + LogPrintf("ConnectSocket() : ioctlsocket non-blocking setting failed, error %s\n", NetworkErrorString(WSAGetLastError())); #else if (fcntl(hSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR) - LogPrintf("ConnectSocket() : fcntl non-blocking setting failed, error %d\n", errno); + LogPrintf("ConnectSocket() : fcntl non-blocking setting failed, error %s\n", NetworkErrorString(errno)); #endif // Add node @@ -736,7 +736,7 @@ void SocketSendData(CNode *pnode) int nErr = WSAGetLastError(); if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS) { - LogPrintf("socket send error %d\n", nErr); + LogPrintf("socket send error %s\n", NetworkErrorString(nErr)); pnode->CloseSocketDisconnect(); } } @@ -896,7 +896,7 @@ void ThreadSocketHandler() if (have_fds) { int nErr = WSAGetLastError(); - LogPrintf("socket select error %d\n", nErr); + LogPrintf("socket select error %s\n", NetworkErrorString(nErr)); for (unsigned int i = 0; i <= hSocketMax; i++) FD_SET(i, &fdsetRecv); } @@ -933,7 +933,7 @@ void ThreadSocketHandler() { int nErr = WSAGetLastError(); if (nErr != WSAEWOULDBLOCK) - LogPrintf("socket error accept failed: %d\n", nErr); + LogPrintf("socket error accept failed: %s\n", NetworkErrorString(nErr)); } else if (nInbound >= nMaxConnections - MAX_OUTBOUND_CONNECTIONS) { @@ -1007,7 +1007,7 @@ void ThreadSocketHandler() if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS) { if (!pnode->fDisconnect) - LogPrintf("socket recv error %d\n", nErr); + LogPrintf("socket recv error %s\n", NetworkErrorString(nErr)); pnode->CloseSocketDisconnect(); } } @@ -1458,13 +1458,13 @@ bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOu // for now, use a very simple selection metric: the node from which we received // most recently -double static NodeSyncScore(const CNode *pnode) { - return -pnode->nLastRecv; +static int64_t NodeSyncScore(const CNode *pnode) { + return pnode->nLastRecv; } void static StartSync(const vector &vNodes) { CNode *pnodeNewSync = NULL; - double dBestScore = 0; + int64_t nBestScore = 0; int nBestHeight = g_signals.GetHeight().get_value_or(0); @@ -1476,10 +1476,10 @@ void static StartSync(const vector &vNodes) { (pnode->nStartingHeight > (nBestHeight - 144)) && (pnode->nVersion < NOBLKS_VERSION_START || pnode->nVersion >= NOBLKS_VERSION_END)) { // if ok, compare node's score with the best so far - double dScore = NodeSyncScore(pnode); - if (pnodeNewSync == NULL || dScore > dBestScore) { + int64_t nScore = NodeSyncScore(pnode); + if (pnodeNewSync == NULL || nScore > nBestScore) { pnodeNewSync = pnode; - dBestScore = dScore; + nBestScore = nScore; } } } @@ -1585,7 +1585,7 @@ bool BindListenPort(const CService &addrBind, string& strError) SOCKET hListenSocket = socket(((struct sockaddr*)&sockaddr)->sa_family, SOCK_STREAM, IPPROTO_TCP); if (hListenSocket == INVALID_SOCKET) { - strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError()); + strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %s)", NetworkErrorString(WSAGetLastError())); LogPrintf("%s\n", strError); return false; } @@ -1609,7 +1609,7 @@ bool BindListenPort(const CService &addrBind, string& strError) if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR) #endif { - strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError()); + strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %s)", NetworkErrorString(WSAGetLastError())); LogPrintf("%s\n", strError); return false; } @@ -1638,7 +1638,7 @@ bool BindListenPort(const CService &addrBind, string& strError) if (nErr == WSAEADDRINUSE) strError = strprintf(_("Unable to bind to %s on this computer. Dogecoin Core Daemon is probably already running."), addrBind.ToString()); else - strError = strprintf(_("Unable to bind to %s on this computer (bind returned error %d, %s)"), addrBind.ToString(), nErr, strerror(nErr)); + strError = strprintf(_("Unable to bind to %s on this computer (bind returned error %s)"), addrBind.ToString(), NetworkErrorString(nErr)); LogPrintf("%s\n", strError); return false; } @@ -1647,7 +1647,7 @@ bool BindListenPort(const CService &addrBind, string& strError) // Listen for incoming connections if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR) { - strError = strprintf(_("Error: Listening for incoming connections failed (listen returned error %d)"), WSAGetLastError()); + strError = strprintf(_("Error: Listening for incoming connections failed (listen returned error %s)"), NetworkErrorString(WSAGetLastError())); LogPrintf("%s\n", strError); return false; } @@ -1785,7 +1785,7 @@ public: BOOST_FOREACH(SOCKET hListenSocket, vhListenSocket) if (hListenSocket != INVALID_SOCKET) if (closesocket(hListenSocket) == SOCKET_ERROR) - LogPrintf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError()); + LogPrintf("closesocket(hListenSocket) failed with error %s\n", NetworkErrorString(WSAGetLastError())); // clean up some globals (to help leak detection) BOOST_FOREACH(CNode *pnode, vNodes) diff --git a/src/net.h b/src/net.h index 729b1bcd5..f9b953c8d 100644 --- a/src/net.h +++ b/src/net.h @@ -255,7 +255,7 @@ public: // flood relay std::vector vAddrToSend; - std::set setAddrKnown; + mruset setAddrKnown; bool fGetAddr; std::set setKnown; @@ -271,7 +271,7 @@ public: int64_t nPingUsecTime; bool fPingQueued; - CNode(SOCKET hSocketIn, CAddress addrIn, std::string addrNameIn = "", bool fInboundIn=false) : ssSend(SER_NETWORK, INIT_PROTO_VERSION) + CNode(SOCKET hSocketIn, CAddress addrIn, std::string addrNameIn = "", bool fInboundIn=false) : ssSend(SER_NETWORK, INIT_PROTO_VERSION), setAddrKnown(5000) { nServices = 0; hSocket = hSocketIn; diff --git a/src/netbase.cpp b/src/netbase.cpp index 82a681281..e24a0a195 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -361,7 +361,7 @@ bool static ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRe } if (nRet == SOCKET_ERROR) { - LogPrintf("select() for %s failed: %i\n", addrConnect.ToString(), WSAGetLastError()); + LogPrintf("select() for %s failed: %s\n", addrConnect.ToString(), NetworkErrorString(WSAGetLastError())); closesocket(hSocket); return false; } @@ -372,13 +372,13 @@ bool static ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRe if (getsockopt(hSocket, SOL_SOCKET, SO_ERROR, &nRet, &nRetSize) == SOCKET_ERROR) #endif { - LogPrintf("getsockopt() for %s failed: %i\n", addrConnect.ToString(), WSAGetLastError()); + LogPrintf("getsockopt() for %s failed: %s\n", addrConnect.ToString(), NetworkErrorString(WSAGetLastError())); closesocket(hSocket); return false; } if (nRet != 0) { - LogPrintf("connect() to %s failed after select(): %s\n", addrConnect.ToString(), strerror(nRet)); + LogPrintf("connect() to %s failed after select(): %s\n", addrConnect.ToString(), NetworkErrorString(nRet)); closesocket(hSocket); return false; } @@ -389,7 +389,7 @@ bool static ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRe else #endif { - LogPrintf("connect() to %s failed: %i\n", addrConnect.ToString(), WSAGetLastError()); + LogPrintf("connect() to %s failed: %s\n", addrConnect.ToString(), NetworkErrorString(WSAGetLastError())); closesocket(hSocket); return false; } @@ -1237,3 +1237,36 @@ bool operator!=(const CSubNet& a, const CSubNet& b) { return !(a==b); } + +#ifdef WIN32 +std::string NetworkErrorString(int err) +{ + char buf[256]; + buf[0] = 0; + if(FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_MAX_WIDTH_MASK, + NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + buf, sizeof(buf), NULL)) + { + return strprintf("%s (%d)", buf, err); + } + else + { + return strprintf("Unknown error (%d)", err); + } +} +#else +std::string NetworkErrorString(int err) +{ + char buf[256]; + const char *s = buf; + buf[0] = 0; + /* Too bad there are two incompatible implementations of the + * thread-safe strerror. */ +#ifdef STRERROR_R_CHAR_P /* GNU variant can return a pointer outside the passed buffer */ + s = strerror_r(err, buf, sizeof(buf)); +#else /* POSIX variant always returns message in buffer */ + (void) strerror_r(err, buf, sizeof(buf)); +#endif + return strprintf("%s (%d)", s, err); +} +#endif diff --git a/src/netbase.h b/src/netbase.h index 118f866d6..5fd8be4ac 100644 --- a/src/netbase.h +++ b/src/netbase.h @@ -179,5 +179,7 @@ bool Lookup(const char *pszName, std::vector& vAddr, int portDefault = bool LookupNumeric(const char *pszName, CService& addr, int portDefault = 0); bool ConnectSocket(const CService &addr, SOCKET& hSocketRet, int nTimeout = nConnectTimeout); bool ConnectSocketByName(CService &addr, SOCKET& hSocketRet, const char *pszDest, int portDefault = 0, int nTimeout = nConnectTimeout); +/** Return readable error string for a network error code */ +std::string NetworkErrorString(int err); #endif diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index c738c4152..9763335bb 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -463,6 +463,8 @@ WId BitcoinApplication::getMainWinId() const #ifndef BITCOIN_QT_TEST int main(int argc, char *argv[]) { + SetupEnvironment(); + /// 1. Parse command-line options. These take precedence over anything else. // Command-line options take precedence: ParseParameters(argc, argv); diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index 6460d0bff..b6d6ca09f 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -575,7 +575,7 @@ bool SetStartOnSystemStartup(bool fAutoStart) return true; } -#elif defined(LINUX) +#elif defined(Q_OS_LINUX) // Follow the Desktop Application Autostart Spec: // http://standards.freedesktop.org/autostart-spec/autostart-spec-latest.html diff --git a/src/qt/macdockiconhandler.mm b/src/qt/macdockiconhandler.mm index 64291c918..74fb64ace 100644 --- a/src/qt/macdockiconhandler.mm +++ b/src/qt/macdockiconhandler.mm @@ -62,6 +62,8 @@ MacDockIconHandler::MacDockIconHandler() : QObject() this->setMainWindow(NULL); #if QT_VERSION < 0x050000 qt_mac_set_dock_menu(this->m_dockMenu); +#elif QT_VERSION >= 0x050200 + this->m_dockMenu->setAsDockMenu(); #endif [pool release]; } diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index 518b3f9c1..545d62134 100644 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -64,8 +64,8 @@ Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex) BOOST_FOREACH(const CTransaction&tx, block.vtx) txs.push_back(tx.GetHash().GetHex()); result.push_back(Pair("tx", txs)); - result.push_back(Pair("time", (boost::int64_t)block.GetBlockTime())); - result.push_back(Pair("nonce", (boost::uint64_t)block.nNonce)); + result.push_back(Pair("time", block.GetBlockTime())); + result.push_back(Pair("nonce", (uint64_t)block.nNonce)); result.push_back(Pair("bits", HexBits(block.nBits))); result.push_back(Pair("difficulty", GetDifficulty(blockindex))); result.push_back(Pair("chainwork", blockindex->nChainWork.GetHex())); @@ -175,7 +175,7 @@ Value getrawmempool(const Array& params, bool fHelp) Object info; info.push_back(Pair("size", (int)e.GetTxSize())); info.push_back(Pair("fee", ValueFromAmount(e.GetFee()))); - info.push_back(Pair("time", (boost::int64_t)e.GetTime())); + info.push_back(Pair("time", e.GetTime())); info.push_back(Pair("height", (int)e.GetHeight())); info.push_back(Pair("startingpriority", e.GetPriority(e.GetHeight()))); info.push_back(Pair("currentpriority", e.GetPriority(chainActive.Height()))); @@ -315,11 +315,11 @@ Value gettxoutsetinfo(const Array& params, bool fHelp) CCoinsStats stats; if (pcoinsTip->GetStats(stats)) { - ret.push_back(Pair("height", (boost::int64_t)stats.nHeight)); + ret.push_back(Pair("height", (int64_t)stats.nHeight)); ret.push_back(Pair("bestblock", stats.hashBlock.GetHex())); - ret.push_back(Pair("transactions", (boost::int64_t)stats.nTransactions)); - ret.push_back(Pair("txouts", (boost::int64_t)stats.nTransactionOutputs)); - ret.push_back(Pair("bytes_serialized", (boost::int64_t)stats.nSerializedSize)); + ret.push_back(Pair("transactions", (int64_t)stats.nTransactions)); + ret.push_back(Pair("txouts", (int64_t)stats.nTransactionOutputs)); + ret.push_back(Pair("bytes_serialized", (int64_t)stats.nSerializedSize)); ret.push_back(Pair("hash_serialized", stats.hashSerialized.GetHex())); ret.push_back(Pair("total_amount", ValueFromAmount(stats.nTotalAmount))); } diff --git a/src/rpcclient.cpp b/src/rpcclient.cpp index 84d2cefc9..d46d164bb 100644 --- a/src/rpcclient.cpp +++ b/src/rpcclient.cpp @@ -129,53 +129,53 @@ Array RPCConvertValues(const std::string &strMethod, const std::vector 0) ConvertTo(params[0]); if (strMethod == "getaddednodeinfo" && n > 0) ConvertTo(params[0]); if (strMethod == "setgenerate" && n > 0) ConvertTo(params[0]); - if (strMethod == "setgenerate" && n > 1) ConvertTo(params[1]); - if (strMethod == "getnetworkhashps" && n > 0) ConvertTo(params[0]); - if (strMethod == "getnetworkhashps" && n > 1) ConvertTo(params[1]); + if (strMethod == "setgenerate" && n > 1) ConvertTo(params[1]); + if (strMethod == "getnetworkhashps" && n > 0) ConvertTo(params[0]); + if (strMethod == "getnetworkhashps" && n > 1) ConvertTo(params[1]); if (strMethod == "sendtoaddress" && n > 1) ConvertTo(params[1]); if (strMethod == "settxfee" && n > 0) ConvertTo(params[0]); - if (strMethod == "getreceivedbyaddress" && n > 1) ConvertTo(params[1]); - if (strMethod == "getreceivedbyaccount" && n > 1) ConvertTo(params[1]); - if (strMethod == "listreceivedbyaddress" && n > 0) ConvertTo(params[0]); + if (strMethod == "getreceivedbyaddress" && n > 1) ConvertTo(params[1]); + if (strMethod == "getreceivedbyaccount" && n > 1) ConvertTo(params[1]); + if (strMethod == "listreceivedbyaddress" && n > 0) ConvertTo(params[0]); if (strMethod == "listreceivedbyaddress" && n > 1) ConvertTo(params[1]); - if (strMethod == "listreceivedbyaccount" && n > 0) ConvertTo(params[0]); + if (strMethod == "listreceivedbyaccount" && n > 0) ConvertTo(params[0]); if (strMethod == "listreceivedbyaccount" && n > 1) ConvertTo(params[1]); - if (strMethod == "getbalance" && n > 1) ConvertTo(params[1]); - if (strMethod == "getblockhash" && n > 0) ConvertTo(params[0]); + if (strMethod == "getbalance" && n > 1) ConvertTo(params[1]); + if (strMethod == "getblockhash" && n > 0) ConvertTo(params[0]); if (strMethod == "move" && n > 2) ConvertTo(params[2]); - if (strMethod == "move" && n > 3) ConvertTo(params[3]); + if (strMethod == "move" && n > 3) ConvertTo(params[3]); if (strMethod == "sendfrom" && n > 2) ConvertTo(params[2]); - if (strMethod == "sendfrom" && n > 3) ConvertTo(params[3]); - if (strMethod == "listtransactions" && n > 1) ConvertTo(params[1]); - if (strMethod == "listtransactions" && n > 2) ConvertTo(params[2]); - if (strMethod == "listaccounts" && n > 0) ConvertTo(params[0]); - if (strMethod == "walletpassphrase" && n > 1) ConvertTo(params[1]); + if (strMethod == "sendfrom" && n > 3) ConvertTo(params[3]); + if (strMethod == "listtransactions" && n > 1) ConvertTo(params[1]); + if (strMethod == "listtransactions" && n > 2) ConvertTo(params[2]); + if (strMethod == "listaccounts" && n > 0) ConvertTo(params[0]); + if (strMethod == "walletpassphrase" && n > 1) ConvertTo(params[1]); if (strMethod == "getblocktemplate" && n > 0) ConvertTo(params[0]); - if (strMethod == "listsinceblock" && n > 1) ConvertTo(params[1]); + if (strMethod == "listsinceblock" && n > 1) ConvertTo(params[1]); if (strMethod == "sendmany" && n > 1) ConvertTo(params[1]); - if (strMethod == "sendmany" && n > 2) ConvertTo(params[2]); - if (strMethod == "addmultisigaddress" && n > 0) ConvertTo(params[0]); + if (strMethod == "sendmany" && n > 2) ConvertTo(params[2]); + if (strMethod == "addmultisigaddress" && n > 0) ConvertTo(params[0]); if (strMethod == "addmultisigaddress" && n > 1) ConvertTo(params[1]); - if (strMethod == "createmultisig" && n > 0) ConvertTo(params[0]); + if (strMethod == "createmultisig" && n > 0) ConvertTo(params[0]); if (strMethod == "createmultisig" && n > 1) ConvertTo(params[1]); - if (strMethod == "listunspent" && n > 0) ConvertTo(params[0]); - if (strMethod == "listunspent" && n > 1) ConvertTo(params[1]); + if (strMethod == "listunspent" && n > 0) ConvertTo(params[0]); + if (strMethod == "listunspent" && n > 1) ConvertTo(params[1]); if (strMethod == "listunspent" && n > 2) ConvertTo(params[2]); if (strMethod == "getblock" && n > 1) ConvertTo(params[1]); - if (strMethod == "getrawtransaction" && n > 1) ConvertTo(params[1]); + if (strMethod == "getrawtransaction" && n > 1) ConvertTo(params[1]); if (strMethod == "createrawtransaction" && n > 0) ConvertTo(params[0]); if (strMethod == "createrawtransaction" && n > 1) ConvertTo(params[1]); if (strMethod == "signrawtransaction" && n > 1) ConvertTo(params[1], true); if (strMethod == "signrawtransaction" && n > 2) ConvertTo(params[2], true); if (strMethod == "sendrawtransaction" && n > 1) ConvertTo(params[1], true); - if (strMethod == "gettxout" && n > 1) ConvertTo(params[1]); + if (strMethod == "gettxout" && n > 1) ConvertTo(params[1]); if (strMethod == "gettxout" && n > 2) ConvertTo(params[2]); if (strMethod == "lockunspent" && n > 0) ConvertTo(params[0]); if (strMethod == "lockunspent" && n > 1) ConvertTo(params[1]); if (strMethod == "importprivkey" && n > 2) ConvertTo(params[2]); - if (strMethod == "verifychain" && n > 0) ConvertTo(params[0]); - if (strMethod == "verifychain" && n > 1) ConvertTo(params[1]); - if (strMethod == "keypoolrefill" && n > 0) ConvertTo(params[0]); + if (strMethod == "verifychain" && n > 0) ConvertTo(params[0]); + if (strMethod == "verifychain" && n > 1) ConvertTo(params[1]); + if (strMethod == "keypoolrefill" && n > 0) ConvertTo(params[0]); if (strMethod == "getrawmempool" && n > 0) ConvertTo(params[0]); return params; diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index 1cfcd9eca..368d6d25a 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -91,7 +91,7 @@ Value GetNetworkHashPS(int lookup, int height) { uint256 workDiff = pb->nChainWork - pb0->nChainWork; int64_t timeDiff = maxTime - minTime; - return (boost::int64_t)(workDiff.getdouble() / timeDiff); + return (int64_t)(workDiff.getdouble() / timeDiff); } Value getnetworkhashps(const Array& params, bool fHelp) @@ -229,8 +229,8 @@ Value gethashespersec(const Array& params, bool fHelp) ); if (GetTimeMillis() - nHPSTimerStart > 8000) - return (boost::int64_t)0; - return (boost::int64_t)dHashesPerSec; + return (int64_t)0; + return (int64_t)dHashesPerSec; } #endif diff --git a/src/rpcmisc.cpp b/src/rpcmisc.cpp index a56e58cc3..267516c82 100644 --- a/src/rpcmisc.cpp +++ b/src/rpcmisc.cpp @@ -69,18 +69,18 @@ Value getinfo(const Array& params, bool fHelp) } #endif obj.push_back(Pair("blocks", (int)chainActive.Height())); - obj.push_back(Pair("timeoffset", (boost::int64_t)GetTimeOffset())); + obj.push_back(Pair("timeoffset", GetTimeOffset())); obj.push_back(Pair("connections", (int)vNodes.size())); obj.push_back(Pair("proxy", (proxy.first.IsValid() ? proxy.first.ToStringIPPort() : string()))); obj.push_back(Pair("difficulty", (double)GetDifficulty())); obj.push_back(Pair("testnet", TestNet())); #ifdef ENABLE_WALLET if (pwalletMain) { - obj.push_back(Pair("keypoololdest", (boost::int64_t)pwalletMain->GetOldestKeyPoolTime())); + obj.push_back(Pair("keypoololdest", pwalletMain->GetOldestKeyPoolTime())); obj.push_back(Pair("keypoolsize", (int)pwalletMain->GetKeyPoolSize())); } if (pwalletMain && pwalletMain->IsCrypted()) - obj.push_back(Pair("unlocked_until", (boost::int64_t)nWalletUnlockTime)); + obj.push_back(Pair("unlocked_until", nWalletUnlockTime)); obj.push_back(Pair("paytxfee", ValueFromAmount(nTransactionFee))); #endif obj.push_back(Pair("relayfee", ValueFromAmount(CTransaction::nMinRelayTxFee))); diff --git a/src/rpcnet.cpp b/src/rpcnet.cpp index 0faa49c2f..f5d8fad49 100644 --- a/src/rpcnet.cpp +++ b/src/rpcnet.cpp @@ -116,11 +116,11 @@ Value getpeerinfo(const Array& params, bool fHelp) if (!(stats.addrLocal.empty())) obj.push_back(Pair("addrlocal", stats.addrLocal)); obj.push_back(Pair("services", strprintf("%08x", stats.nServices))); - obj.push_back(Pair("lastsend", (boost::int64_t)stats.nLastSend)); - obj.push_back(Pair("lastrecv", (boost::int64_t)stats.nLastRecv)); - obj.push_back(Pair("bytessent", (boost::int64_t)stats.nSendBytes)); - obj.push_back(Pair("bytesrecv", (boost::int64_t)stats.nRecvBytes)); - obj.push_back(Pair("conntime", (boost::int64_t)stats.nTimeConnected)); + obj.push_back(Pair("lastsend", stats.nLastSend)); + obj.push_back(Pair("lastrecv", stats.nLastRecv)); + obj.push_back(Pair("bytessent", stats.nSendBytes)); + obj.push_back(Pair("bytesrecv", stats.nRecvBytes)); + obj.push_back(Pair("conntime", stats.nTimeConnected)); obj.push_back(Pair("pingtime", stats.dPingTime)); if (stats.dPingWait > 0.0) obj.push_back(Pair("pingwait", stats.dPingWait)); @@ -329,9 +329,9 @@ Value getnettotals(const Array& params, bool fHelp) ); Object obj; - obj.push_back(Pair("totalbytesrecv", static_cast< boost::uint64_t>(CNode::GetTotalBytesRecv()))); - obj.push_back(Pair("totalbytessent", static_cast(CNode::GetTotalBytesSent()))); - obj.push_back(Pair("timemillis", static_cast(GetTimeMillis()))); + obj.push_back(Pair("totalbytesrecv", CNode::GetTotalBytesRecv())); + obj.push_back(Pair("totalbytessent", CNode::GetTotalBytesSent())); + obj.push_back(Pair("timemillis", GetTimeMillis())); return obj; } @@ -366,7 +366,7 @@ Value getnetworkinfo(const Array& params, bool fHelp) Object obj; obj.push_back(Pair("version", (int)CLIENT_VERSION)); obj.push_back(Pair("protocolversion",(int)PROTOCOL_VERSION)); - obj.push_back(Pair("timeoffset", (boost::int64_t)GetTimeOffset())); + obj.push_back(Pair("timeoffset", GetTimeOffset())); obj.push_back(Pair("connections", (int)vNodes.size())); obj.push_back(Pair("proxy", (proxy.first.IsValid() ? proxy.first.ToStringIPPort() : string()))); obj.push_back(Pair("relayfee", ValueFromAmount(CTransaction::nMinRelayTxFee))); diff --git a/src/rpcprotocol.cpp b/src/rpcprotocol.cpp index 5bb3e62b4..18392a718 100644 --- a/src/rpcprotocol.cpp +++ b/src/rpcprotocol.cpp @@ -52,15 +52,7 @@ string HTTPPost(const string& strMsg, const map& mapRequestHeader static string rfc1123Time() { - char buffer[64]; - time_t now; - time(&now); - struct tm* now_gmt = gmtime(&now); - string locale(setlocale(LC_TIME, NULL)); - setlocale(LC_TIME, "C"); // we want POSIX (aka "C") weekday/month strings - strftime(buffer, sizeof(buffer), "%a, %d %b %Y %H:%M:%S +0000", now_gmt); - setlocale(LC_TIME, locale.c_str()); - return string(buffer); + return DateTimeStrFormat("%a, %d %b %Y %H:%M:%S +0000", GetTime()); } string HTTPReply(int nStatus, const string& strMsg, bool keepalive) diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp index 5d1c6a9d3..8dec20c33 100644 --- a/src/rpcrawtransaction.cpp +++ b/src/rpcrawtransaction.cpp @@ -55,7 +55,7 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, Object& entry) { entry.push_back(Pair("txid", tx.GetHash().GetHex())); entry.push_back(Pair("version", tx.nVersion)); - entry.push_back(Pair("locktime", (boost::int64_t)tx.nLockTime)); + entry.push_back(Pair("locktime", (int64_t)tx.nLockTime)); Array vin; BOOST_FOREACH(const CTxIn& txin, tx.vin) { @@ -65,13 +65,13 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, Object& entry) else { in.push_back(Pair("txid", txin.prevout.hash.GetHex())); - in.push_back(Pair("vout", (boost::int64_t)txin.prevout.n)); + in.push_back(Pair("vout", (int64_t)txin.prevout.n)); Object o; o.push_back(Pair("asm", txin.scriptSig.ToString())); o.push_back(Pair("hex", HexStr(txin.scriptSig.begin(), txin.scriptSig.end()))); in.push_back(Pair("scriptSig", o)); } - in.push_back(Pair("sequence", (boost::int64_t)txin.nSequence)); + in.push_back(Pair("sequence", (int64_t)txin.nSequence)); vin.push_back(in); } entry.push_back(Pair("vin", vin)); @@ -81,7 +81,7 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, Object& entry) const CTxOut& txout = tx.vout[i]; Object out; out.push_back(Pair("value", ValueFromAmount(txout.nValue))); - out.push_back(Pair("n", (boost::int64_t)i)); + out.push_back(Pair("n", (int64_t)i)); Object o; ScriptPubKeyToJSON(txout.scriptPubKey, o, true); out.push_back(Pair("scriptPubKey", o)); @@ -99,8 +99,8 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, Object& entry) if (chainActive.Contains(pindex)) { entry.push_back(Pair("confirmations", 1 + chainActive.Height() - pindex->nHeight)); - entry.push_back(Pair("time", (boost::int64_t)pindex->nTime)); - entry.push_back(Pair("blocktime", (boost::int64_t)pindex->nTime)); + entry.push_back(Pair("time", (int64_t)pindex->nTime)); + entry.push_back(Pair("blocktime", (int64_t)pindex->nTime)); } else entry.push_back(Pair("confirmations", 0)); diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp index 0e9c17b61..b8a195d34 100644 --- a/src/rpcserver.cpp +++ b/src/rpcserver.cpp @@ -602,7 +602,6 @@ void StartRPCThreads() try { boost::shared_ptr acceptor(new ip::tcp::acceptor(*rpc_io_service)); - rpc_acceptors.push_back(acceptor); acceptor->open(endpoint.protocol()); acceptor->set_option(boost::asio::ip::tcp::acceptor::reuse_address(true)); @@ -614,6 +613,7 @@ void StartRPCThreads() RPCListen(acceptor, *rpc_ssl_context, fUseSSL); + rpc_acceptors.push_back(acceptor); fListening = true; } catch(boost::system::system_error &e) @@ -628,7 +628,6 @@ void StartRPCThreads() endpoint.address(bindAddress); boost::shared_ptr acceptor(new ip::tcp::acceptor(*rpc_io_service)); - rpc_acceptors.push_back(acceptor); acceptor->open(endpoint.protocol()); acceptor->set_option(boost::asio::ip::tcp::acceptor::reuse_address(true)); acceptor->bind(endpoint); @@ -636,6 +635,7 @@ void StartRPCThreads() RPCListen(acceptor, *rpc_ssl_context, fUseSSL); + rpc_acceptors.push_back(acceptor); fListening = true; } } @@ -675,11 +675,20 @@ void StopRPCThreads() // First, cancel all timers and acceptors // This is not done automatically by ->stop(), and in some cases the destructor of // asio::io_service can hang if this is skipped. + boost::system::error_code ec; BOOST_FOREACH(const boost::shared_ptr &acceptor, rpc_acceptors) - acceptor->cancel(); + { + acceptor->cancel(ec); + if (ec) + LogPrintf("%s: Warning: %s when cancelling acceptor", __func__, ec.message()); + } rpc_acceptors.clear(); BOOST_FOREACH(const PAIRTYPE(std::string, boost::shared_ptr) &timer, deadlineTimers) - timer.second->cancel(); + { + timer.second->cancel(ec); + if (ec) + LogPrintf("%s: Warning: %s when cancelling timer", __func__, ec.message()); + } deadlineTimers.clear(); rpc_io_service->stop(); diff --git a/src/rpcwallet.cpp b/src/rpcwallet.cpp index a39d0890e..4ceedd7fd 100644 --- a/src/rpcwallet.cpp +++ b/src/rpcwallet.cpp @@ -49,7 +49,7 @@ void WalletTxToJSON(const CWalletTx& wtx, Object& entry) { entry.push_back(Pair("blockhash", wtx.hashBlock.GetHex())); entry.push_back(Pair("blockindex", wtx.nIndex)); - entry.push_back(Pair("blocktime", (boost::int64_t)(mapBlockIndex[wtx.hashBlock]->nTime))); + entry.push_back(Pair("blocktime", (int64_t)(mapBlockIndex[wtx.hashBlock]->nTime))); } uint256 hash = wtx.GetHash(); entry.push_back(Pair("txid", hash.GetHex())); @@ -57,8 +57,8 @@ void WalletTxToJSON(const CWalletTx& wtx, Object& entry) BOOST_FOREACH(const uint256& conflict, wtx.GetConflicts()) conflicts.push_back(conflict.GetHex()); entry.push_back(Pair("walletconflicts", conflicts)); - entry.push_back(Pair("time", (boost::int64_t)wtx.GetTxTime())); - entry.push_back(Pair("timereceived", (boost::int64_t)wtx.nTimeReceived)); + entry.push_back(Pair("time", wtx.GetTxTime())); + entry.push_back(Pair("timereceived", (int64_t)wtx.nTimeReceived)); BOOST_FOREACH(const PAIRTYPE(string,string)& item, wtx.mapValue) entry.push_back(Pair(item.first, item.second)); } @@ -318,7 +318,7 @@ Value sendtoaddress(const Array& params, bool fHelp) " to which you're sending the transaction. This is not part of the \n" " transaction, just kept in your wallet.\n" "\nResult:\n" - "\"transactionid\" (string) The transaction id. (view at https://blockchain.info/tx/[transactionid])\n" + "\"transactionid\" (string) The transaction id.\n" "\nExamples:\n" + HelpExampleCli("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.1") + HelpExampleCli("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.1 \"donation\" \"seans outpost\"") @@ -747,7 +747,7 @@ Value sendfrom(const Array& params, bool fHelp) " to which you're sending the transaction. This is not part of the transaction, \n" " it is just kept in your wallet.\n" "\nResult:\n" - "\"transactionid\" (string) The transaction id. (view at https://blockchain.info/tx/[transactionid])\n" + "\"transactionid\" (string) The transaction id.\n" "\nExamples:\n" "\nSend 10.01 doge from the default account to the address, must have at least 1 confirmation\n" + HelpExampleCli("sendfrom", "\"\" \"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 10.01") + @@ -807,7 +807,7 @@ Value sendmany(const Array& params, bool fHelp) "4. \"comment\" (string, optional) A comment\n" "\nResult:\n" "\"transactionid\" (string) The transaction id for the send. Only 1 transaction is created regardless of \n" - " the number of addresses. See https://blockchain.info/tx/[transactionid]\n" + " the number of addresses.\n" "\nExamples:\n" "\nSend two amounts to two different addresses:\n" + HelpExampleCli("sendmany", "\"tabby\" \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\"") + @@ -1167,7 +1167,7 @@ void AcentryToJSON(const CAccountingEntry& acentry, const string& strAccount, Ar Object entry; entry.push_back(Pair("account", acentry.strAccount)); entry.push_back(Pair("category", "move")); - entry.push_back(Pair("time", (boost::int64_t)acentry.nTime)); + entry.push_back(Pair("time", acentry.nTime)); entry.push_back(Pair("amount", ValueFromAmount(acentry.nCreditDebit))); entry.push_back(Pair("otheraccount", acentry.strOtherAccount)); entry.push_back(Pair("comment", acentry.strComment)); @@ -1209,8 +1209,7 @@ Value listtransactions(const Array& params, bool fHelp) " category of transactions.\n" " \"blockindex\": n, (numeric) The block index containing the transaction. Available for 'send' and 'receive'\n" " category of transactions.\n" - " \"txid\": \"transactionid\", (string) The transaction id (see https://blockchain.info/tx/[transactionid]. Available \n" - " for 'send' and 'receive' category of transactions.\n" + " \"txid\": \"transactionid\", (string) The transaction id. Available for 'send' and 'receive' category of transactions.\n" " \"time\": xxx, (numeric) The transaction time in seconds since epoch (midnight Jan 1 1970 GMT).\n" " \"timereceived\": xxx, (numeric) The time received in seconds since epoch (midnight Jan 1 1970 GMT). Available \n" " for 'send' and 'receive' category of transactions.\n" @@ -1375,7 +1374,7 @@ Value listsinceblock(const Array& params, bool fHelp) " \"blockhash\": \"hashvalue\", (string) The block hash containing the transaction. Available for 'send' and 'receive' category of transactions.\n" " \"blockindex\": n, (numeric) The block index containing the transaction. Available for 'send' and 'receive' category of transactions.\n" " \"blocktime\": xxx, (numeric) The block time in seconds since epoch (1 Jan 1970 GMT).\n" - " \"txid\": \"transactionid\", (string) The transaction id (see https://blockchain.info/tx/[transactionid]. Available for 'send' and 'receive' category of transactions.\n" + " \"txid\": \"transactionid\", (string) The transaction id. Available for 'send' and 'receive' category of transactions.\n" " \"time\": xxx, (numeric) The transaction time in seconds since epoch (Jan 1 1970 GMT).\n" " \"timereceived\": xxx, (numeric) The time received in seconds since epoch (Jan 1 1970 GMT). Available for 'send' and 'receive' category of transactions.\n" " \"comment\": \"...\", (string) If a comment is associated with the transaction.\n" @@ -1447,7 +1446,7 @@ Value gettransaction(const Array& params, bool fHelp) " \"blockhash\" : \"hash\", (string) The block hash\n" " \"blockindex\" : xx, (numeric) The block index\n" " \"blocktime\" : ttt, (numeric) The time in seconds since epoch (1 Jan 1970 GMT)\n" - " \"txid\" : \"transactionid\", (string) The transaction id, see also https://blockchain.info/tx/[transactionid]\n" + " \"txid\" : \"transactionid\", (string) The transaction id.\n" " \"time\" : ttt, (numeric) The transaction time in seconds since epoch (1 Jan 1970 GMT)\n" " \"timereceived\" : ttt, (numeric) The time received in seconds since epoch (1 Jan 1970 GMT)\n" " \"details\" : [\n" @@ -1912,9 +1911,9 @@ Value getwalletinfo(const Array& params, bool fHelp) obj.push_back(Pair("walletversion", pwalletMain->GetVersion())); obj.push_back(Pair("balance", ValueFromAmount(pwalletMain->GetBalance()))); obj.push_back(Pair("txcount", (int)pwalletMain->mapWallet.size())); - obj.push_back(Pair("keypoololdest", (boost::int64_t)pwalletMain->GetOldestKeyPoolTime())); + obj.push_back(Pair("keypoololdest", pwalletMain->GetOldestKeyPoolTime())); obj.push_back(Pair("keypoolsize", (int)pwalletMain->GetKeyPoolSize())); if (pwalletMain->IsCrypted()) - obj.push_back(Pair("unlocked_until", (boost::int64_t)nWalletUnlockTime)); + obj.push_back(Pair("unlocked_until", nWalletUnlockTime)); return obj; } diff --git a/src/test/base58_tests.cpp b/src/test/base58_tests.cpp index 5689e6999..b81a19cfd 100644 --- a/src/test/base58_tests.cpp +++ b/src/test/base58_tests.cpp @@ -233,7 +233,7 @@ BOOST_AUTO_TEST_CASE(base58_keys_valid_gen) continue; } CBitcoinAddress addrOut; - BOOST_CHECK_MESSAGE(boost::apply_visitor(CBitcoinAddressVisitor(&addrOut), dest), "encode dest: " + strTest); + BOOST_CHECK_MESSAGE(addrOut.Set(dest), "encode dest: " + strTest); BOOST_CHECK_MESSAGE(addrOut.ToString() == exp_base58string, "mismatch: " + strTest); } } @@ -241,7 +241,7 @@ BOOST_AUTO_TEST_CASE(base58_keys_valid_gen) // Visiting a CNoDestination must fail CBitcoinAddress dummyAddr; CTxDestination nodest = CNoDestination(); - BOOST_CHECK(!boost::apply_visitor(CBitcoinAddressVisitor(&dummyAddr), nodest)); + BOOST_CHECK(!dummyAddr.Set(nodest)); SelectParams(CChainParams::MAIN); } diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp index f4ca8c053..092d48063 100644 --- a/src/test/util_tests.cpp +++ b/src/test/util_tests.cpp @@ -108,13 +108,11 @@ BOOST_AUTO_TEST_CASE(util_HexStr) BOOST_AUTO_TEST_CASE(util_DateTimeStrFormat) { -/*These are platform-dependant and thus removed to avoid useless test failures BOOST_CHECK_EQUAL(DateTimeStrFormat("%Y-%m-%d %H:%M:%S", 0), "1970-01-01 00:00:00"); BOOST_CHECK_EQUAL(DateTimeStrFormat("%Y-%m-%d %H:%M:%S", 0x7FFFFFFF), "2038-01-19 03:14:07"); - // Formats used within Bitcoin BOOST_CHECK_EQUAL(DateTimeStrFormat("%Y-%m-%d %H:%M:%S", 1317425777), "2011-09-30 23:36:17"); BOOST_CHECK_EQUAL(DateTimeStrFormat("%Y-%m-%d %H:%M", 1317425777), "2011-09-30 23:36"); -*/ + BOOST_CHECK_EQUAL(DateTimeStrFormat("%a, %d %b %Y %H:%M:%S +0000", 1317425777), "Fri, 30 Sep 2011 23:36:17 +0000"); } BOOST_AUTO_TEST_CASE(util_ParseParameters) diff --git a/src/util.cpp b/src/util.cpp index f8eb9a658..d1f76f6a5 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -16,6 +16,8 @@ #include +#include + #ifndef WIN32 // for posix_fallocate #ifdef __linux_ @@ -306,26 +308,6 @@ int LogPrintStr(const std::string &str) return ret; } -void ParseString(const string& str, char c, vector& v) -{ - if (str.empty()) - return; - string::size_type i1 = 0; - string::size_type i2; - while (true) - { - i2 = str.find(c, i1); - if (i2 == str.npos) - { - v.push_back(str.substr(i1)); - return; - } - v.push_back(str.substr(i1, i2-i1)); - i1 = i2+1; - } -} - - string FormatMoney(int64_t n, bool fPlus) { // Note: not using straight sprintf here because we do NOT want @@ -1448,4 +1430,29 @@ bool ParseInt32(const std::string& str, int32_t *out) n >= std::numeric_limits::min() && n <= std::numeric_limits::max(); } +void SetupEnvironment() +{ + #ifndef WIN32 + try + { + #if BOOST_FILESYSTEM_VERSION == 3 + boost::filesystem::path::codecvt(); // Raises runtime error if current locale is invalid + #else // boost filesystem v2 + std::locale(); // Raises runtime error if current locale is invalid + #endif + } catch(std::runtime_error &e) + { + setenv("LC_ALL", "C", 1); // Force C locale + } + #endif +} +std::string DateTimeStrFormat(const char* pszFormat, int64_t nTime) +{ + // std::locale takes ownership of the pointer + std::locale loc(std::locale::classic(), new boost::posix_time::time_facet(pszFormat)); + std::stringstream ss; + ss.imbue(loc); + ss << boost::posix_time::from_time_t(nTime); + return ss.str(); +} diff --git a/src/util.h b/src/util.h index 63fce428b..002946149 100644 --- a/src/util.h +++ b/src/util.h @@ -121,6 +121,7 @@ extern volatile bool fReopenDebugLog; void RandAddSeed(); void RandAddSeedPerfmon(); +void SetupEnvironment(); /* Return true if log accepts specified category */ bool LogAcceptCategory(const char* category); @@ -168,7 +169,6 @@ static inline bool error(const char* format) void LogException(std::exception* pex, const char* pszThread); void PrintExceptionContinue(std::exception* pex, const char* pszThread); -void ParseString(const std::string& str, char c, std::vector& v); std::string FormatMoney(int64_t n, bool fPlus=false); bool ParseMoney(const std::string& str, int64_t& nRet); bool ParseMoney(const char* pszIn, int64_t& nRet); @@ -341,14 +341,7 @@ inline int64_t GetTimeMicros() boost::posix_time::ptime(boost::gregorian::date(1970,1,1))).total_microseconds(); } -inline std::string DateTimeStrFormat(const char* pszFormat, int64_t nTime) -{ - time_t n = nTime; - struct tm* ptmTime = gmtime(&n); - char pszTime[200]; - strftime(pszTime, sizeof(pszTime), pszFormat, ptmTime); - return pszTime; -} +std::string DateTimeStrFormat(const char* pszFormat, int64_t nTime); inline bool IsSwitchChar(char c) { diff --git a/src/wallet.h b/src/wallet.h index 1fac70f8c..3f2b9fbf1 100644 --- a/src/wallet.h +++ b/src/wallet.h @@ -329,6 +329,17 @@ public: unsigned int nMasterKeyMaxID; CWallet() + { + SetNull(); + } + CWallet(std::string strWalletFileIn) + { + SetNull(); + + strWalletFile = strWalletFileIn; + fFileBacked = true; + } + void SetNull() { nWalletVersion = FEATURE_BASE; nWalletMaxVersion = FEATURE_BASE; @@ -338,18 +349,7 @@ public: nOrderPosNext = 0; nNextResend = 0; nLastResend = 0; - } - CWallet(std::string strWalletFileIn) - { - nWalletVersion = FEATURE_BASE; - nWalletMaxVersion = FEATURE_BASE; - strWalletFile = strWalletFileIn; - fFileBacked = true; - nMasterKeyMaxID = 0; - pwalletdbEncryption = NULL; - nOrderPosNext = 0; - nNextResend = 0; - nLastResend = 0; + nTimeFirstKey = 0; } std::map mapWallet;