mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-01-21 15:50:07 +01:00
Compare commits
423 Commits
v0.19-fina
...
v0.6.3rc1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6e0c5e3778 | ||
|
|
23e7583a8c | ||
|
|
b90b8159db | ||
|
|
bd05d057eb | ||
|
|
c58ff3781d | ||
|
|
57ca021e7e | ||
|
|
4bd6299efd | ||
|
|
fcbeaff8d0 | ||
|
|
414e0407df | ||
|
|
7c1773cf37 | ||
|
|
28a498d5a6 | ||
|
|
2d90330d8c | ||
|
|
4d87a33eae | ||
|
|
63ee422ab3 | ||
|
|
469f6da8bc | ||
|
|
87593b9837 | ||
|
|
4aa8021a96 | ||
|
|
db4036a829 | ||
|
|
5e322a72f9 | ||
|
|
6ec9d30905 | ||
|
|
3703150d56 | ||
|
|
8f0c0c16d3 | ||
|
|
1bc2f0a37b | ||
|
|
276cfd8530 | ||
|
|
0b1fda6f65 | ||
|
|
ca39829ecb | ||
|
|
a973e225e7 | ||
|
|
5482b5d23b | ||
|
|
1903033bad | ||
|
|
b825e816e4 | ||
|
|
01ed45cbbc | ||
|
|
9849f50b68 | ||
|
|
9a48f56fb0 | ||
|
|
722ff53718 | ||
|
|
af413c0a0f | ||
|
|
a0ea95d3ce | ||
|
|
fdd907c9f1 | ||
|
|
7c4de78a5c | ||
|
|
82a227b263 | ||
|
|
17badef789 | ||
|
|
a49927a46d | ||
|
|
d67b0434f2 | ||
|
|
3b36da6d27 | ||
|
|
a2de1ea2d5 | ||
|
|
b6862f7b74 | ||
|
|
d7534272c6 | ||
|
|
8a39b0d613 | ||
|
|
087fc28f7d | ||
|
|
58ac600b2c | ||
|
|
b2de28c740 | ||
|
|
d11488abd0 | ||
|
|
e10622d129 | ||
|
|
334668cde4 | ||
|
|
c45c2c380d | ||
|
|
77b0f86a43 | ||
|
|
fba681519a | ||
|
|
3a05f1d2ce | ||
|
|
738592a002 | ||
|
|
c455aec699 | ||
|
|
10593f3be1 | ||
|
|
dc15d56b2d | ||
|
|
0d174e130b | ||
|
|
182738e177 | ||
|
|
7532c476fe | ||
|
|
d306fd833c | ||
|
|
7700b94d33 | ||
|
|
7515f00aa3 | ||
|
|
9e52f51223 | ||
|
|
93b5eff274 | ||
|
|
99101685f6 | ||
|
|
40fd689eb1 | ||
|
|
aaff04791d | ||
|
|
f0f1b3775e | ||
|
|
ca0816152d | ||
|
|
91b13a0dff | ||
|
|
8f9123a157 | ||
|
|
8fa3259664 | ||
|
|
cd0527453b | ||
|
|
35a07f8ec4 | ||
|
|
fac3476993 | ||
|
|
18b4eccddb | ||
|
|
8ff1873096 | ||
|
|
b481373001 | ||
|
|
1fa846bbb6 | ||
|
|
b803009c84 | ||
|
|
60953d05c8 | ||
|
|
6bcefc1338 | ||
|
|
afff998ef0 | ||
|
|
2403bb79bc | ||
|
|
eb3f661add | ||
|
|
5e27f737fa | ||
|
|
05ff9680ba | ||
|
|
dfdaee9310 | ||
|
|
5cbe24202a | ||
|
|
293f2644ff | ||
|
|
486f7c8f65 | ||
|
|
e38d492822 | ||
|
|
9b661e57bf | ||
|
|
457ff3a437 | ||
|
|
5da2dce524 | ||
|
|
700e5a4d86 | ||
|
|
adecb2ea00 | ||
|
|
e2b9bf9e6e | ||
|
|
b94e6eb5a5 | ||
|
|
d41f22cb76 | ||
|
|
607739befb | ||
|
|
479c99022e | ||
|
|
65077e1177 | ||
|
|
ee932c6e35 | ||
|
|
c328c684c2 | ||
|
|
57cd445e95 | ||
|
|
a1a5a89063 | ||
|
|
b2e5f797b5 | ||
|
|
6a89317f62 | ||
|
|
ad5a4c7c47 | ||
|
|
cae1a68267 | ||
|
|
6789e99e4f | ||
|
|
4898482915 | ||
|
|
8edec3f9d6 | ||
|
|
e6578e7fa7 | ||
|
|
1fb6e2d9bf | ||
|
|
6c055e506d | ||
|
|
813dc92cdc | ||
|
|
3a70f3a4ec | ||
|
|
655b1b0cc2 | ||
|
|
dd02f3ca6e | ||
|
|
824e8dde8b | ||
|
|
b7a2b6e1aa | ||
|
|
5ad4028050 | ||
|
|
8ba4282c3f | ||
|
|
e5f43fe309 | ||
|
|
ccfcdc2e3d | ||
|
|
c18b82d5db | ||
|
|
3eb5fdbf5f | ||
|
|
aff6456e8a | ||
|
|
ea22a380de | ||
|
|
dfac636fd7 | ||
|
|
282e3ffe6e | ||
|
|
c21121752d | ||
|
|
07d1a50aee | ||
|
|
66116c3847 | ||
|
|
a93ab87787 | ||
|
|
d0fe14ffec | ||
|
|
c43a9ea77d | ||
|
|
e5b980d72f | ||
|
|
8104274701 | ||
|
|
bd043f19c8 | ||
|
|
e401e5eb79 | ||
|
|
dc588faf59 | ||
|
|
7f34351910 | ||
|
|
1b7e5cbcad | ||
|
|
2abd083ea4 | ||
|
|
0c3aa881e2 | ||
|
|
774e9b6dbb | ||
|
|
ef2f3ddaf7 | ||
|
|
d506c160eb | ||
|
|
1175d8f6a1 | ||
|
|
12570da46f | ||
|
|
e2ce6438a9 | ||
|
|
3374c3ef09 | ||
|
|
e73b792b1a | ||
|
|
79fc752b61 | ||
|
|
1bdfa94a01 | ||
|
|
8460185dec | ||
|
|
9c236a945c | ||
|
|
678a319888 | ||
|
|
0aa0bb1ead | ||
|
|
fdcafa3535 | ||
|
|
5f4fee559e | ||
|
|
c4381587a6 | ||
|
|
85e975f379 | ||
|
|
f650d62fc6 | ||
|
|
401db6d96b | ||
|
|
7c3db2129e | ||
|
|
cb1035a008 | ||
|
|
79940a6793 | ||
|
|
e962c7f532 | ||
|
|
b7566fe29c | ||
|
|
b557c17a37 | ||
|
|
02a38ac22b | ||
|
|
f2862f1a49 | ||
|
|
a558054709 | ||
|
|
1f91797535 | ||
|
|
e88b6b341d | ||
|
|
278074eb23 | ||
|
|
760d9480ed | ||
|
|
1f56046fd5 | ||
|
|
06de079091 | ||
|
|
9bf1140b90 | ||
|
|
527b512cf7 | ||
|
|
892fcaf291 | ||
|
|
bf1f995c4c | ||
|
|
ce33356094 | ||
|
|
d652709aba | ||
|
|
8ae76e0f5d | ||
|
|
a93bb51604 | ||
|
|
3e0e10add3 | ||
|
|
0d10cb7a1f | ||
|
|
0af2f2d856 | ||
|
|
c7057326ea | ||
|
|
53e596512c | ||
|
|
d02833c76a | ||
|
|
bf754cfd01 | ||
|
|
fe1725a141 | ||
|
|
658cf0b1be | ||
|
|
a37092fcf4 | ||
|
|
91d7e847e0 | ||
|
|
1376cd9d7f | ||
|
|
ef9ab3c2a0 | ||
|
|
724c65c1f8 | ||
|
|
8fae3dae11 | ||
|
|
6806677841 | ||
|
|
3f47eb4a9a | ||
|
|
2f98e8c1a4 | ||
|
|
1fafcee66d | ||
|
|
d53fbb4a53 | ||
|
|
d15180297f | ||
|
|
60f89779a3 | ||
|
|
dce656f9e0 | ||
|
|
2eba535348 | ||
|
|
ddd0d9ae54 | ||
|
|
9a133240d3 | ||
|
|
6085033f31 | ||
|
|
9504e415cb | ||
|
|
fea0a27ddc | ||
|
|
1941765ae2 | ||
|
|
04dc79f1cc | ||
|
|
b6751ed1b2 | ||
|
|
8ed1f7c153 | ||
|
|
68d889db34 | ||
|
|
e364ad962f | ||
|
|
166004aca5 | ||
|
|
fcc547346a | ||
|
|
d1eafe56c8 | ||
|
|
2ac8af4534 | ||
|
|
cdc6b8d6a6 | ||
|
|
815a3605c1 | ||
|
|
17a5fd9248 | ||
|
|
2f2ac3fece | ||
|
|
0e6c6e3fd1 | ||
|
|
b4c7b6a384 | ||
|
|
e20417c333 | ||
|
|
0ae535cdb2 | ||
|
|
1194f00350 | ||
|
|
00d832756c | ||
|
|
0a1c5c9b10 | ||
|
|
b3ba40c6bf | ||
|
|
1a4ac2b4d0 | ||
|
|
1422e5bf51 | ||
|
|
8b3a795ea6 | ||
|
|
1db5f43dc4 | ||
|
|
c1c86b147b | ||
|
|
eca170286e | ||
|
|
78b9d2de40 | ||
|
|
27960a36de | ||
|
|
91aadbdacf | ||
|
|
458b6e6436 | ||
|
|
7f23df06d7 | ||
|
|
f322aa4d60 | ||
|
|
ffef16404d | ||
|
|
76a3bfa17c | ||
|
|
4986c35d74 | ||
|
|
d05c03ab4e | ||
|
|
b4f8c8f5f9 | ||
|
|
11c34e0f6c | ||
|
|
b3b4b008e3 | ||
|
|
9cf600e6da | ||
|
|
7013cc3d97 | ||
|
|
88aa771536 | ||
|
|
4fc8c042a2 | ||
|
|
e9865a41d6 | ||
|
|
d7962747c4 | ||
|
|
3108aed0f2 | ||
|
|
ef48e9b7df | ||
|
|
0b11082d36 | ||
|
|
feb3c15335 | ||
|
|
1be5779124 | ||
|
|
ab2be34059 | ||
|
|
54fee2d0ce | ||
|
|
001a64c71c | ||
|
|
b085138f89 | ||
|
|
471e0bdc7c | ||
|
|
caad1add4f | ||
|
|
33e0c3a866 | ||
|
|
82705af1eb | ||
|
|
69ce70866d | ||
|
|
6fb186f4bb | ||
|
|
fdb365df0e | ||
|
|
8960f2fc33 | ||
|
|
43163a5a4d | ||
|
|
fb811c31fd | ||
|
|
0365f19dec | ||
|
|
25be0597ca | ||
|
|
6928794f56 | ||
|
|
d52397b3c0 | ||
|
|
622f1438de | ||
|
|
41cde5bbdc | ||
|
|
6ebb141bf9 | ||
|
|
4c38fbae95 | ||
|
|
9ab932b769 | ||
|
|
8ad6996cc3 | ||
|
|
888ac4e7a3 | ||
|
|
76e707a44e | ||
|
|
84d228ed83 | ||
|
|
a21e4da901 | ||
|
|
b5d9c7d9fb | ||
|
|
4bbd72cca1 | ||
|
|
da6a3919a9 | ||
|
|
e7c3e6e4b4 | ||
|
|
ccd69c7d22 | ||
|
|
4664aae3fe | ||
|
|
cac23a5a0b | ||
|
|
06e0f79ae5 | ||
|
|
882e00e215 | ||
|
|
c11e2b8679 | ||
|
|
d841fc969a | ||
|
|
c13d50d861 | ||
|
|
c1c6de6ad4 | ||
|
|
7120874983 | ||
|
|
1b6d8f3fca | ||
|
|
e5b031f5d2 | ||
|
|
edb563e8a5 | ||
|
|
bccbc5f4c3 | ||
|
|
22388eac08 | ||
|
|
1677743fca | ||
|
|
d1e56838dc | ||
|
|
a0db9a79e5 | ||
|
|
8f378e98c5 | ||
|
|
3d3f9cd120 | ||
|
|
5df1a22c2e | ||
|
|
54ed0a0432 | ||
|
|
b0870346f2 | ||
|
|
1181bf86d1 | ||
|
|
382e613ef5 | ||
|
|
c144672045 | ||
|
|
a5b875f47b | ||
|
|
70550ed81b | ||
|
|
5df96269d3 | ||
|
|
948072c39f | ||
|
|
880c478635 | ||
|
|
98811f6ad4 | ||
|
|
83201b12ae | ||
|
|
507848b63d | ||
|
|
cc19ba76e4 | ||
|
|
6e1e62a04c | ||
|
|
9b53650a45 | ||
|
|
2d8bc0e6da | ||
|
|
21aa161453 | ||
|
|
09308a3882 | ||
|
|
7de7913abd | ||
|
|
780a182317 | ||
|
|
99e9601e80 | ||
|
|
45099b19da | ||
|
|
a2e9767225 | ||
|
|
20e3f2aefc | ||
|
|
fb88f1cc97 | ||
|
|
eb2a10afd6 | ||
|
|
cc6bd19660 | ||
|
|
84393f15b6 | ||
|
|
b52b6f2e38 | ||
|
|
a91a40febd | ||
|
|
3b8051864b | ||
|
|
961cf14ab3 | ||
|
|
8632383161 | ||
|
|
ab4b52a239 | ||
|
|
96f1723bb1 | ||
|
|
027d149352 | ||
|
|
96c700f5e4 | ||
|
|
f503a1486a | ||
|
|
987f26aa1a | ||
|
|
6be2c9b5b4 | ||
|
|
7aa253d3ec | ||
|
|
9ea0699278 | ||
|
|
f1a6d74775 | ||
|
|
5fe2dbd7b6 | ||
|
|
ace5ce05be | ||
|
|
98c0b8b85e | ||
|
|
1f53204045 | ||
|
|
181b863d22 | ||
|
|
142e5056cd | ||
|
|
9a7f4948c6 | ||
|
|
12c69167e3 | ||
|
|
b379bc5eef | ||
|
|
16e7c05de7 | ||
|
|
4c519a47a9 | ||
|
|
ba56a88ca5 | ||
|
|
fe5cc3b7f8 | ||
|
|
5d901f1ba0 | ||
|
|
0e6425da4a | ||
|
|
f8c3eb9568 | ||
|
|
d27be1f557 | ||
|
|
3741185a51 | ||
|
|
cba18514c0 | ||
|
|
a7d735dcc2 | ||
|
|
094c35cffc | ||
|
|
b683118cd0 | ||
|
|
1c4be55a99 | ||
|
|
7597fcd92f | ||
|
|
adb9f7ddde | ||
|
|
99fe0af2fe | ||
|
|
45593c271a | ||
|
|
d885aba347 | ||
|
|
36b1eb7631 | ||
|
|
76ef6d89b9 | ||
|
|
c4a3bf9e55 | ||
|
|
90de05e88e | ||
|
|
2bf36b4e7d | ||
|
|
831d24a19d | ||
|
|
1aafd7464f | ||
|
|
586ea168c2 | ||
|
|
1179f6373d | ||
|
|
0143c024af | ||
|
|
2744ea8c1f | ||
|
|
00eae584a2 | ||
|
|
ef4280e08b | ||
|
|
ed176ba584 | ||
|
|
38a976d5bb | ||
|
|
b526cbaa71 | ||
|
|
aec5c5fe26 | ||
|
|
600dc62559 | ||
|
|
030d7acf7d | ||
|
|
20cff2ade4 | ||
|
|
7944d81567 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,6 +1,7 @@
|
||||
src/*.exe
|
||||
src/bitcoin
|
||||
src/bitcoind
|
||||
src/test_bitcoin
|
||||
src/build.h
|
||||
.*.swp
|
||||
*.*~*
|
||||
@@ -20,3 +21,4 @@ qrc_*.cpp
|
||||
*.pro.user
|
||||
#mac specific
|
||||
.DS_Store
|
||||
build
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
TEMPLATE = app
|
||||
TARGET =
|
||||
VERSION = 0.6.1
|
||||
VERSION = 0.6.3.0
|
||||
INCLUDEPATH += src src/json src/qt
|
||||
DEFINES += QT_GUI BOOST_THREAD_USE_LIB
|
||||
DEFINES += QT_GUI BOOST_THREAD_USE_LIB BOOST_SPIRIT_THREADSAFE
|
||||
CONFIG += no_include_pwd
|
||||
|
||||
# for boost 1.37, add -mt to the boost libraries
|
||||
@@ -83,7 +83,7 @@ contains(BITCOIN_NEED_QT_PLUGINS, 1) {
|
||||
# regenerate src/build.h
|
||||
!windows || contains(USE_BUILD_INFO, 1) {
|
||||
genbuild.depends = FORCE
|
||||
genbuild.commands = cd $$PWD; share/genbuild.sh $$OUT_PWD/build/build.h
|
||||
genbuild.commands = cd $$PWD; /bin/sh share/genbuild.sh $$OUT_PWD/build/build.h
|
||||
genbuild.target = genbuildhook
|
||||
PRE_TARGETDEPS += genbuildhook
|
||||
QMAKE_EXTRA_TARGETS += genbuild
|
||||
|
||||
@@ -35,7 +35,7 @@ Description: peer-to-peer network based digital currency - daemon
|
||||
By default connects to an IRC network to discover other peers.
|
||||
.
|
||||
Full transaction history is stored locally at each client. This
|
||||
requires 150+ MB of space, slowly growing.
|
||||
requires 2+ GB of space, slowly growing.
|
||||
.
|
||||
This package provides bitcoind, a combined daemon and CLI tool to
|
||||
interact with the daemon.
|
||||
@@ -53,6 +53,6 @@ Description: peer-to-peer network based digital currency - QT GUI
|
||||
By default connects to an IRC network to discover other peers.
|
||||
.
|
||||
Full transaction history is stored locally at each client. This
|
||||
requires 150+ MB of space, slowly growing.
|
||||
requires 2+ GB of space, slowly growing.
|
||||
.
|
||||
This package provides bitcoin-qt, a GUI for Bitcoin based on QT.
|
||||
|
||||
@@ -31,7 +31,7 @@ signers:
|
||||
weight: 40
|
||||
name: "Gavin Andresen"
|
||||
key: gavinandresen
|
||||
71A3B16735405025D447E8F274810B012346C9A6
|
||||
71A3B16735405025D447E8F274810B012346C9A6:
|
||||
weight: 40
|
||||
name: "Wladimir J. van der Laan"
|
||||
key: laanwj
|
||||
|
||||
@@ -31,7 +31,7 @@ signers:
|
||||
weight: 40
|
||||
name: "Gavin Andresen"
|
||||
key: gavinandresen
|
||||
71A3B16735405025D447E8F274810B012346C9A6
|
||||
71A3B16735405025D447E8F274810B012346C9A6:
|
||||
weight: 40
|
||||
name: "Wladimir J. van der Laan"
|
||||
key: laanwj
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Bitcoin 0.6.1 BETA
|
||||
Bitcoin 0.6.3 BETA
|
||||
|
||||
Copyright (c) 2009-2012 Bitcoin Developers
|
||||
Distributed under the MIT/X11 software license, see the accompanying
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Bitcoin 0.6.1 BETA
|
||||
Bitcoin 0.6.3 BETA
|
||||
|
||||
Copyright (c) 2009-2012 Bitcoin Developers
|
||||
Distributed under the MIT/X11 software license, see the accompanying
|
||||
|
||||
@@ -33,14 +33,14 @@ Dependencies
|
||||
miniupnpc may be used for UPnP port mapping. It can be downloaded from
|
||||
http://miniupnp.tuxfamily.org/files/. UPnP support is compiled in and
|
||||
turned off by default. Set USE_UPNP to a different value to control this:
|
||||
USE_UPNP= No UPnP support - miniupnp not required
|
||||
USE_UPNP=- No UPnP support - miniupnp not required
|
||||
USE_UPNP=0 (the default) UPnP support turned off by default at runtime
|
||||
USE_UPNP=1 UPnP support turned on by default at runtime
|
||||
|
||||
libqrencode may be used for QRCode image generation. It can be downloaded
|
||||
from http://fukuchi.org/works/qrencode/index.html.en, or installed via
|
||||
your package manager. Set USE_QRCODE to control this:
|
||||
USE_QRCODE=0 (the default) No QRCode support - libarcode not required
|
||||
USE_QRCODE=0 (the default) No QRCode support - libqrcode not required
|
||||
USE_QRCODE=1 QRCode support enabled
|
||||
|
||||
Licenses of statically linked libraries:
|
||||
|
||||
@@ -98,6 +98,8 @@
|
||||
|
||||
* update wiki download links
|
||||
|
||||
* update wiki changelog: https://en.bitcoin.it/wiki/Changelog
|
||||
|
||||
* Commit your signature to gitian.sigs:
|
||||
pushd gitian.sigs
|
||||
git add ${VERSION}/${SIGNER}
|
||||
|
||||
@@ -5,7 +5,7 @@ SetCompressor /SOLID lzma
|
||||
|
||||
# General Symbol Definitions
|
||||
!define REGKEY "SOFTWARE\$(^Name)"
|
||||
!define VERSION 0.6.1
|
||||
!define VERSION 0.6.3
|
||||
!define COMPANY "Bitcoin project"
|
||||
!define URL http://www.bitcoin.org/
|
||||
|
||||
@@ -45,13 +45,13 @@ Var StartMenuGroup
|
||||
!insertmacro MUI_LANGUAGE English
|
||||
|
||||
# Installer attributes
|
||||
OutFile bitcoin-0.6.1-win32-setup.exe
|
||||
OutFile bitcoin-0.6.3-win32-setup.exe
|
||||
InstallDir $PROGRAMFILES\Bitcoin
|
||||
CRCCheck on
|
||||
XPStyle on
|
||||
BrandingText " "
|
||||
ShowInstDetails show
|
||||
VIProductVersion 0.6.1.3
|
||||
VIProductVersion 0.6.3.0
|
||||
VIAddVersionKey ProductName Bitcoin
|
||||
VIAddVersionKey ProductVersion "${VERSION}"
|
||||
VIAddVersionKey CompanyName "${COMPANY}"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Copyright (c) 2012 Pieter Wuille
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "addrman.h"
|
||||
|
||||
@@ -107,9 +107,15 @@ void CAddrMan::SwapRandom(int nRndPos1, int nRndPos2)
|
||||
if (nRndPos1 == nRndPos2)
|
||||
return;
|
||||
|
||||
assert(nRndPos1 >= 0 && nRndPos2 >= 0);
|
||||
assert(nRndPos1 < vRandom.size() && nRndPos2 < vRandom.size());
|
||||
|
||||
int nId1 = vRandom[nRndPos1];
|
||||
int nId2 = vRandom[nRndPos2];
|
||||
|
||||
assert(mapInfo.count(nId1) == 1);
|
||||
assert(mapInfo.count(nId2) == 1);
|
||||
|
||||
mapInfo[nId1].nRandomPos = nRndPos2;
|
||||
mapInfo[nId2].nRandomPos = nRndPos1;
|
||||
|
||||
@@ -124,26 +130,32 @@ int CAddrMan::SelectTried(int nKBucket)
|
||||
// random shuffle the first few elements (using the entire list)
|
||||
// find the least recently tried among them
|
||||
int64 nOldest = -1;
|
||||
int nOldestPos = -1;
|
||||
for (unsigned int i = 0; i < ADDRMAN_TRIED_ENTRIES_INSPECT_ON_EVICT && i < vTried.size(); i++)
|
||||
{
|
||||
int nPos = GetRandInt(vTried.size() - i) + i;
|
||||
int nTemp = vTried[nPos];
|
||||
vTried[nPos] = vTried[i];
|
||||
vTried[i] = nTemp;
|
||||
if (nOldest == -1 || mapInfo[nTemp].nLastSuccess < mapInfo[nOldest].nLastSuccess)
|
||||
assert(nOldest == -1 || mapInfo.count(nTemp) == 1);
|
||||
if (nOldest == -1 || mapInfo[nTemp].nLastSuccess < mapInfo[nOldest].nLastSuccess) {
|
||||
nOldest = nTemp;
|
||||
nOldestPos = nPos;
|
||||
}
|
||||
}
|
||||
|
||||
return nOldest;
|
||||
return nOldestPos;
|
||||
}
|
||||
|
||||
int CAddrMan::ShrinkNew(int nUBucket)
|
||||
{
|
||||
assert(nUBucket >= 0 && nUBucket < vvNew.size());
|
||||
std::set<int> &vNew = vvNew[nUBucket];
|
||||
|
||||
// first look for deletable items
|
||||
for (std::set<int>::iterator it = vNew.begin(); it != vNew.end(); it++)
|
||||
{
|
||||
assert(mapInfo.count(*it));
|
||||
CAddrInfo &info = mapInfo[*it];
|
||||
if (info.IsTerrible())
|
||||
{
|
||||
@@ -168,11 +180,13 @@ int CAddrMan::ShrinkNew(int nUBucket)
|
||||
{
|
||||
if (nI == n[0] || nI == n[1] || nI == n[2] || nI == n[3])
|
||||
{
|
||||
assert(nOldest == -1 || mapInfo.count(*it) == 1);
|
||||
if (nOldest == -1 || mapInfo[*it].nTime < mapInfo[nOldest].nTime)
|
||||
nOldest = *it;
|
||||
}
|
||||
nI++;
|
||||
}
|
||||
assert(mapInfo.count(nOldest) == 1);
|
||||
CAddrInfo &info = mapInfo[nOldest];
|
||||
if (--info.nRefCount == 0)
|
||||
{
|
||||
@@ -189,6 +203,8 @@ int CAddrMan::ShrinkNew(int nUBucket)
|
||||
|
||||
void CAddrMan::MakeTried(CAddrInfo& info, int nId, int nOrigin)
|
||||
{
|
||||
assert(vvNew[nOrigin].count(nId) == 1);
|
||||
|
||||
// remove the entry from all new buckets
|
||||
for (std::vector<std::set<int> >::iterator it = vvNew.begin(); it != vvNew.end(); it++)
|
||||
{
|
||||
@@ -197,6 +213,8 @@ void CAddrMan::MakeTried(CAddrInfo& info, int nId, int nOrigin)
|
||||
}
|
||||
nNew--;
|
||||
|
||||
assert(info.nRefCount == 0);
|
||||
|
||||
// what tried bucket to move the entry to
|
||||
int nKBucket = info.GetTriedBucket(nKey);
|
||||
std::vector<int> &vTried = vvTried[nKBucket];
|
||||
@@ -214,6 +232,7 @@ void CAddrMan::MakeTried(CAddrInfo& info, int nId, int nOrigin)
|
||||
int nPos = SelectTried(nKBucket);
|
||||
|
||||
// find which new bucket it belongs to
|
||||
assert(mapInfo.count(vTried[nPos]) == 1);
|
||||
int nUBucket = mapInfo[vTried[nPos]].GetNewBucket(nKey);
|
||||
std::set<int> &vNew = vvNew[nUBucket];
|
||||
|
||||
@@ -385,6 +404,7 @@ CAddress CAddrMan::Select_(int nUnkBias)
|
||||
std::vector<int> &vTried = vvTried[nKBucket];
|
||||
if (vTried.size() == 0) continue;
|
||||
int nPos = GetRandInt(vTried.size());
|
||||
assert(mapInfo.count(vTried[nPos]) == 1);
|
||||
CAddrInfo &info = mapInfo[vTried[nPos]];
|
||||
if (GetRandInt(1<<30) < fChanceFactor*info.GetChance()*(1<<30))
|
||||
return info;
|
||||
@@ -402,6 +422,7 @@ CAddress CAddrMan::Select_(int nUnkBias)
|
||||
std::set<int>::iterator it = vNew.begin();
|
||||
while (nPos--)
|
||||
it++;
|
||||
assert(mapInfo.count(*it) == 1);
|
||||
CAddrInfo &info = mapInfo[*it];
|
||||
if (GetRandInt(1<<30) < fChanceFactor*info.GetChance()*(1<<30))
|
||||
return info;
|
||||
@@ -481,6 +502,7 @@ void CAddrMan::GetAddr_(std::vector<CAddress> &vAddr)
|
||||
{
|
||||
int nRndPos = GetRandInt(vRandom.size() - n) + n;
|
||||
SwapRandom(n, nRndPos);
|
||||
assert(mapInfo.count(vRandom[n]) == 1);
|
||||
vAddr.push_back(mapInfo[vRandom[n]]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Copyright (c) 2012 Pieter Wuille
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
#ifndef _BITCOIN_ADDRMAN
|
||||
#define _BITCOIN_ADDRMAN 1
|
||||
|
||||
@@ -62,7 +62,7 @@ public:
|
||||
nRandomPos = -1;
|
||||
}
|
||||
|
||||
CAddrInfo(const CAddress &addrIn, const CNetAddr &addrSource) : CAddress(addrIn)
|
||||
CAddrInfo(const CAddress &addrIn, const CNetAddr &addrSource) : CAddress(addrIn), source(addrSource)
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// 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.
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
#ifndef BITCOIN_ALLOCATORS_H
|
||||
#define BITCOIN_ALLOCATORS_H
|
||||
|
||||
@@ -117,7 +117,6 @@ struct zero_after_free_allocator : public std::allocator<T>
|
||||
};
|
||||
|
||||
// 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;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// 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.
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
||||
//
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// 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.
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
#ifndef BITCOIN_BIGNUM_H
|
||||
#define BITCOIN_BIGNUM_H
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright (c) 2010 Satoshi Nakamoto
|
||||
// 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.
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "main.h"
|
||||
#include "wallet.h"
|
||||
@@ -225,7 +225,7 @@ Value stop(const Array& params, bool fHelp)
|
||||
"stop\n"
|
||||
"Stop bitcoin server.");
|
||||
// Shutdown will take long enough that the response should get back
|
||||
QueueShutdown();
|
||||
StartShutdown();
|
||||
return "bitcoin server stopping";
|
||||
}
|
||||
|
||||
@@ -839,7 +839,8 @@ Value movecmd(const Array& params, bool fHelp)
|
||||
strComment = params[4].get_str();
|
||||
|
||||
CWalletDB walletdb(pwalletMain->strWalletFile);
|
||||
walletdb.TxnBegin();
|
||||
if (!walletdb.TxnBegin())
|
||||
throw JSONRPCError(-20, "database error");
|
||||
|
||||
int64 nNow = GetAdjustedTime();
|
||||
|
||||
@@ -861,7 +862,8 @@ Value movecmd(const Array& params, bool fHelp)
|
||||
credit.strComment = strComment;
|
||||
walletdb.WriteAccountingEntry(credit);
|
||||
|
||||
walletdb.TxnCommit();
|
||||
if (!walletdb.TxnCommit())
|
||||
throw JSONRPCError(-20, "database error");
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -999,10 +1001,12 @@ Value addmultisigaddress(const Array& params, bool fHelp)
|
||||
strAccount = AccountFromValue(params[2]);
|
||||
|
||||
// Gather public keys
|
||||
if ((nRequired < 1) || ((int)keys.size() < nRequired))
|
||||
if (nRequired < 1)
|
||||
throw runtime_error("a multisignature address must require at least one key to redeem");
|
||||
if ((int)keys.size() < nRequired)
|
||||
throw runtime_error(
|
||||
strprintf("wrong number of keys"
|
||||
"(got %d, need at least %d)", keys.size(), nRequired));
|
||||
strprintf("not enough keys supplied "
|
||||
"(got %d keys, but need at least %d to redeem)", keys.size(), nRequired));
|
||||
std::vector<CKey> pubkeys;
|
||||
pubkeys.resize(keys.size());
|
||||
for (unsigned int i = 0; i < keys.size(); i++)
|
||||
@@ -1703,7 +1707,7 @@ Value encryptwallet(const Array& params, bool fHelp)
|
||||
// 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
|
||||
// unencrypted private keys. So:
|
||||
QueueShutdown();
|
||||
StartShutdown();
|
||||
return "wallet encrypted; bitcoin server stopping, restart to run with encrypted wallet";
|
||||
}
|
||||
|
||||
@@ -2376,7 +2380,7 @@ void ThreadRPCServer2(void* parg)
|
||||
GetConfigFile().string().c_str(),
|
||||
EncodeBase58(&rand_pwd[0],&rand_pwd[0]+32).c_str()),
|
||||
_("Error"), wxOK | wxMODAL);
|
||||
QueueShutdown();
|
||||
StartShutdown();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2397,7 +2401,7 @@ void ThreadRPCServer2(void* parg)
|
||||
{
|
||||
ThreadSafeMessageBox(strprintf(_("An error occured while setting up the RPC port %i for listening: %s"), endpoint.port(), e.what()),
|
||||
_("Error"), wxOK | wxMODAL);
|
||||
QueueShutdown();
|
||||
StartShutdown();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright (c) 2010 Satoshi Nakamoto
|
||||
// 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.
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef _BITCOINRPC_H_
|
||||
#define _BITCOINRPC_H_ 1
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// 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.
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <boost/assign/list_of.hpp> // for 'map_list_of()'
|
||||
#include <boost/foreach.hpp>
|
||||
@@ -25,14 +25,11 @@ namespace Checkpoints
|
||||
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"))
|
||||
(185333, uint256("0x00000000000002334c71b8706940c20348af897a9cfc0f1a6dab0d14d4ceb815"))
|
||||
;
|
||||
|
||||
bool CheckBlock(int nHeight, const uint256& hash)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// 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.
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
#ifndef BITCOIN_CHECKPOINT_H
|
||||
#define BITCOIN_CHECKPOINT_H
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// 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.
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
#ifndef _BITCOIN_COMPAT_H
|
||||
#define _BITCOIN_COMPAT_H 1
|
||||
|
||||
|
||||
19
src/db.cpp
19
src/db.cpp
@@ -1,7 +1,7 @@
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// 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.
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "db.h"
|
||||
#include "util.h"
|
||||
@@ -96,6 +96,7 @@ CDB::CDB(const char *pszFile, const char* pszMode) : pdb(NULL)
|
||||
dbenv.set_lk_max_locks(10000);
|
||||
dbenv.set_lk_max_objects(10000);
|
||||
dbenv.set_errfile(fopen(pathErrorFile.string().c_str(), "a")); /// debug
|
||||
dbenv.set_flags(DB_TXN_WRITE_NOSYNC, 1);
|
||||
dbenv.set_flags(DB_AUTO_COMMIT, 1);
|
||||
dbenv.log_set_config(DB_LOG_AUTO_REMOVE, 1);
|
||||
ret = dbenv.open(pathDataDir.string().c_str(),
|
||||
@@ -410,9 +411,15 @@ bool CTxDB::ReadOwnerTxes(uint160 hash160, int nMinHeight, vector<CTransaction>&
|
||||
string strType;
|
||||
uint160 hashItem;
|
||||
CDiskTxPos pos;
|
||||
ssKey >> strType >> hashItem >> pos;
|
||||
int nItemHeight;
|
||||
ssValue >> nItemHeight;
|
||||
|
||||
try {
|
||||
ssKey >> strType >> hashItem >> pos;
|
||||
ssValue >> nItemHeight;
|
||||
}
|
||||
catch (std::exception &e) {
|
||||
return error("%s() : deserialize error", __PRETTY_FUNCTION__);
|
||||
}
|
||||
|
||||
// Read transaction
|
||||
if (strType != "owner" || hashItem != hash160)
|
||||
@@ -532,6 +539,8 @@ bool CTxDB::LoadBlockIndex()
|
||||
return false;
|
||||
|
||||
// Unserialize
|
||||
|
||||
try {
|
||||
string strType;
|
||||
ssKey >> strType;
|
||||
if (strType == "blockindex" && !fRequestShutdown)
|
||||
@@ -563,6 +572,10 @@ bool CTxDB::LoadBlockIndex()
|
||||
{
|
||||
break; // if shutdown requested or finished loading block index
|
||||
}
|
||||
} // try
|
||||
catch (std::exception &e) {
|
||||
return error("%s() : deserialize error", __PRETTY_FUNCTION__);
|
||||
}
|
||||
}
|
||||
pcursor->close();
|
||||
|
||||
|
||||
13
src/db.h
13
src/db.h
@@ -1,7 +1,7 @@
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// 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.
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
#ifndef BITCOIN_DB_H
|
||||
#define BITCOIN_DB_H
|
||||
|
||||
@@ -72,8 +72,13 @@ protected:
|
||||
return false;
|
||||
|
||||
// Unserialize value
|
||||
CDataStream ssValue((char*)datValue.get_data(), (char*)datValue.get_data() + datValue.get_size(), SER_DISK, CLIENT_VERSION);
|
||||
ssValue >> value;
|
||||
try {
|
||||
CDataStream ssValue((char*)datValue.get_data(), (char*)datValue.get_data() + datValue.get_size(), SER_DISK, CLIENT_VERSION);
|
||||
ssValue >> value;
|
||||
}
|
||||
catch (std::exception &e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Clear and free memory
|
||||
memset(datValue.get_data(), 0, datValue.get_size());
|
||||
@@ -216,7 +221,7 @@ public:
|
||||
if (!pdb)
|
||||
return false;
|
||||
DbTxn* ptxn = NULL;
|
||||
int ret = dbenv.txn_begin(GetTxn(), &ptxn, DB_TXN_NOSYNC);
|
||||
int ret = dbenv.txn_begin(GetTxn(), &ptxn, DB_TXN_WRITE_NOSYNC);
|
||||
if (!ptxn || ret != 0)
|
||||
return false;
|
||||
vTxn.push_back(ptxn);
|
||||
|
||||
16
src/init.cpp
16
src/init.cpp
@@ -1,7 +1,7 @@
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// 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.
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
#include "db.h"
|
||||
#include "walletdb.h"
|
||||
#include "bitcoinrpc.h"
|
||||
@@ -36,6 +36,17 @@ void ExitTimeout(void* parg)
|
||||
#endif
|
||||
}
|
||||
|
||||
void StartShutdown()
|
||||
{
|
||||
#ifdef QT_GUI
|
||||
// ensure we leave the Qt main loop for a clean GUI exit (Shutdown() is called in bitcoin.cpp afterwards)
|
||||
QueueShutdown();
|
||||
#else
|
||||
// Without UI, Shutdown() can simply be started in a new thread
|
||||
CreateThread(Shutdown, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
void Shutdown(void* parg)
|
||||
{
|
||||
static CCriticalSection cs_Shutdown;
|
||||
@@ -64,7 +75,10 @@ void Shutdown(void* parg)
|
||||
Sleep(50);
|
||||
printf("Bitcoin exiting\n\n");
|
||||
fExit = true;
|
||||
#ifndef QT_GUI
|
||||
// ensure non UI client get's exited here, but let Bitcoin-Qt reach return 0; in bitcoin.cpp
|
||||
exit(0);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// 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.
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
#ifndef BITCOIN_INIT_H
|
||||
#define BITCOIN_INIT_H
|
||||
|
||||
@@ -9,11 +9,9 @@
|
||||
|
||||
extern CWallet* pwalletMain;
|
||||
|
||||
void StartShutdown();
|
||||
void Shutdown(void* parg);
|
||||
bool AppInit(int argc, char* argv[]);
|
||||
bool AppInit2(int argc, char* argv[]);
|
||||
|
||||
bool GetStartOnSystemStartup();
|
||||
bool SetStartOnSystemStartup(bool fAutoStart);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// 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.
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "irc.h"
|
||||
#include "net.h"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// 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.
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
#ifndef BITCOIN_IRC_H
|
||||
#define BITCOIN_IRC_H
|
||||
|
||||
|
||||
270
src/key.cpp
270
src/key.cpp
@@ -1,9 +1,14 @@
|
||||
// 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.
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <map>
|
||||
|
||||
#include <openssl/ec.h>
|
||||
#include <openssl/ecdsa.h>
|
||||
#include <openssl/obj_mac.h>
|
||||
|
||||
#include "key.h"
|
||||
#include "util.h"
|
||||
|
||||
// Generate a private key from just the secret parameter
|
||||
int EC_KEY_regenerate_key(EC_KEY *eckey, BIGNUM *priv_key)
|
||||
@@ -115,3 +120,264 @@ err:
|
||||
if (Q != NULL) EC_POINT_free(Q);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void CKey::SetCompressedPubKey()
|
||||
{
|
||||
EC_KEY_set_conv_form(pkey, POINT_CONVERSION_COMPRESSED);
|
||||
fCompressedPubKey = true;
|
||||
}
|
||||
|
||||
void CKey::Reset()
|
||||
{
|
||||
fCompressedPubKey = false;
|
||||
pkey = EC_KEY_new_by_curve_name(NID_secp256k1);
|
||||
if (pkey == NULL)
|
||||
throw key_error("CKey::CKey() : EC_KEY_new_by_curve_name failed");
|
||||
fSet = false;
|
||||
}
|
||||
|
||||
CKey::CKey()
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
CKey::CKey(const CKey& b)
|
||||
{
|
||||
pkey = EC_KEY_dup(b.pkey);
|
||||
if (pkey == NULL)
|
||||
throw key_error("CKey::CKey(const CKey&) : EC_KEY_dup failed");
|
||||
fSet = b.fSet;
|
||||
}
|
||||
|
||||
CKey& CKey::operator=(const CKey& b)
|
||||
{
|
||||
if (!EC_KEY_copy(pkey, b.pkey))
|
||||
throw key_error("CKey::operator=(const CKey&) : EC_KEY_copy failed");
|
||||
fSet = b.fSet;
|
||||
return (*this);
|
||||
}
|
||||
|
||||
CKey::~CKey()
|
||||
{
|
||||
EC_KEY_free(pkey);
|
||||
}
|
||||
|
||||
bool CKey::IsNull() const
|
||||
{
|
||||
return !fSet;
|
||||
}
|
||||
|
||||
bool CKey::IsCompressed() const
|
||||
{
|
||||
return fCompressedPubKey;
|
||||
}
|
||||
|
||||
void CKey::MakeNewKey(bool fCompressed)
|
||||
{
|
||||
if (!EC_KEY_generate_key(pkey))
|
||||
throw key_error("CKey::MakeNewKey() : EC_KEY_generate_key failed");
|
||||
if (fCompressed)
|
||||
SetCompressedPubKey();
|
||||
fSet = true;
|
||||
}
|
||||
|
||||
bool CKey::SetPrivKey(const CPrivKey& vchPrivKey)
|
||||
{
|
||||
const unsigned char* pbegin = &vchPrivKey[0];
|
||||
if (!d2i_ECPrivateKey(&pkey, &pbegin, vchPrivKey.size()))
|
||||
return false;
|
||||
fSet = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CKey::SetSecret(const CSecret& vchSecret, bool fCompressed)
|
||||
{
|
||||
EC_KEY_free(pkey);
|
||||
pkey = EC_KEY_new_by_curve_name(NID_secp256k1);
|
||||
if (pkey == NULL)
|
||||
throw key_error("CKey::SetSecret() : EC_KEY_new_by_curve_name failed");
|
||||
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)
|
||||
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;
|
||||
if (fCompressed || fCompressedPubKey)
|
||||
SetCompressedPubKey();
|
||||
return true;
|
||||
}
|
||||
|
||||
CSecret CKey::GetSecret(bool &fCompressed) const
|
||||
{
|
||||
CSecret vchRet;
|
||||
vchRet.resize(32);
|
||||
const BIGNUM *bn = EC_KEY_get0_private_key(pkey);
|
||||
int nBytes = BN_num_bytes(bn);
|
||||
if (bn == NULL)
|
||||
throw key_error("CKey::GetSecret() : EC_KEY_get0_private_key failed");
|
||||
int n=BN_bn2bin(bn,&vchRet[32 - nBytes]);
|
||||
if (n != nBytes)
|
||||
throw key_error("CKey::GetSecret(): BN_bn2bin failed");
|
||||
fCompressed = fCompressedPubKey;
|
||||
return vchRet;
|
||||
}
|
||||
|
||||
CPrivKey CKey::GetPrivKey() const
|
||||
{
|
||||
int nSize = i2d_ECPrivateKey(pkey, NULL);
|
||||
if (!nSize)
|
||||
throw key_error("CKey::GetPrivKey() : i2d_ECPrivateKey failed");
|
||||
CPrivKey vchPrivKey(nSize, 0);
|
||||
unsigned char* pbegin = &vchPrivKey[0];
|
||||
if (i2d_ECPrivateKey(pkey, &pbegin) != nSize)
|
||||
throw key_error("CKey::GetPrivKey() : i2d_ECPrivateKey returned unexpected size");
|
||||
return vchPrivKey;
|
||||
}
|
||||
|
||||
bool CKey::SetPubKey(const std::vector<unsigned char>& vchPubKey)
|
||||
{
|
||||
const unsigned char* pbegin = &vchPubKey[0];
|
||||
if (!o2i_ECPublicKey(&pkey, &pbegin, vchPubKey.size()))
|
||||
return false;
|
||||
fSet = true;
|
||||
if (vchPubKey.size() == 33)
|
||||
SetCompressedPubKey();
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<unsigned char> CKey::GetPubKey() const
|
||||
{
|
||||
int nSize = i2o_ECPublicKey(pkey, NULL);
|
||||
if (!nSize)
|
||||
throw key_error("CKey::GetPubKey() : i2o_ECPublicKey failed");
|
||||
std::vector<unsigned char> vchPubKey(nSize, 0);
|
||||
unsigned char* pbegin = &vchPubKey[0];
|
||||
if (i2o_ECPublicKey(pkey, &pbegin) != nSize)
|
||||
throw key_error("CKey::GetPubKey() : i2o_ECPublicKey returned unexpected size");
|
||||
return vchPubKey;
|
||||
}
|
||||
|
||||
bool CKey::Sign(uint256 hash, std::vector<unsigned char>& vchSig)
|
||||
{
|
||||
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); // Shrink to fit actual size
|
||||
return true;
|
||||
}
|
||||
|
||||
// create a compact signature (65 bytes), which allows reconstructing the used public key
|
||||
// The format is one header byte, followed by two times 32 bytes for the serialized r and s values.
|
||||
// The header byte: 0x1B = first key with even y, 0x1C = first key with odd y,
|
||||
// 0x1D = second key with even y, 0x1E = second key with odd y
|
||||
bool CKey::SignCompact(uint256 hash, std::vector<unsigned char>& vchSig)
|
||||
{
|
||||
bool fOk = false;
|
||||
ECDSA_SIG *sig = ECDSA_do_sign((unsigned char*)&hash, sizeof(hash), pkey);
|
||||
if (sig==NULL)
|
||||
return false;
|
||||
vchSig.clear();
|
||||
vchSig.resize(65,0);
|
||||
int nBitsR = BN_num_bits(sig->r);
|
||||
int nBitsS = BN_num_bits(sig->s);
|
||||
if (nBitsR <= 256 && nBitsS <= 256)
|
||||
{
|
||||
int nRecId = -1;
|
||||
for (int i=0; i<4; i++)
|
||||
{
|
||||
CKey keyRec;
|
||||
keyRec.fSet = true;
|
||||
if (fCompressedPubKey)
|
||||
keyRec.SetCompressedPubKey();
|
||||
if (ECDSA_SIG_recover_key_GFp(keyRec.pkey, sig, (unsigned char*)&hash, sizeof(hash), i, 1) == 1)
|
||||
if (keyRec.GetPubKey() == this->GetPubKey())
|
||||
{
|
||||
nRecId = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (nRecId == -1)
|
||||
throw key_error("CKey::SignCompact() : unable to construct recoverable key");
|
||||
|
||||
vchSig[0] = nRecId+27+(fCompressedPubKey ? 4 : 0);
|
||||
BN_bn2bin(sig->r,&vchSig[33-(nBitsR+7)/8]);
|
||||
BN_bn2bin(sig->s,&vchSig[65-(nBitsS+7)/8]);
|
||||
fOk = true;
|
||||
}
|
||||
ECDSA_SIG_free(sig);
|
||||
return fOk;
|
||||
}
|
||||
|
||||
// reconstruct public key from a compact signature
|
||||
// This is only slightly more CPU intensive than just verifying it.
|
||||
// If this function succeeds, the recovered public key is guaranteed to be valid
|
||||
// (the signature is a valid signature of the given data for that key)
|
||||
bool CKey::SetCompactSignature(uint256 hash, const std::vector<unsigned char>& vchSig)
|
||||
{
|
||||
if (vchSig.size() != 65)
|
||||
return false;
|
||||
int nV = vchSig[0];
|
||||
if (nV<27 || nV>=35)
|
||||
return false;
|
||||
ECDSA_SIG *sig = ECDSA_SIG_new();
|
||||
BN_bin2bn(&vchSig[1],32,sig->r);
|
||||
BN_bin2bn(&vchSig[33],32,sig->s);
|
||||
|
||||
EC_KEY_free(pkey);
|
||||
pkey = EC_KEY_new_by_curve_name(NID_secp256k1);
|
||||
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 true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CKey::Verify(uint256 hash, const std::vector<unsigned char>& vchSig)
|
||||
{
|
||||
// -1 = error, 0 = bad sig, 1 = good
|
||||
if (ECDSA_verify(0, (unsigned char*)&hash, sizeof(hash), &vchSig[0], vchSig.size(), pkey) != 1)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CKey::VerifyCompact(uint256 hash, const std::vector<unsigned char>& vchSig)
|
||||
{
|
||||
CKey key;
|
||||
if (!key.SetCompactSignature(hash, vchSig))
|
||||
return false;
|
||||
if (GetPubKey() != key.GetPubKey())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CKey::IsValid()
|
||||
{
|
||||
if (!fSet)
|
||||
return false;
|
||||
|
||||
bool fCompr;
|
||||
CSecret secret = GetSecret(fCompr);
|
||||
CKey key2;
|
||||
key2.SetSecret(secret, fCompr);
|
||||
return GetPubKey() == key2.GetPubKey();
|
||||
}
|
||||
|
||||
270
src/key.h
270
src/key.h
@@ -1,20 +1,18 @@
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// 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.
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
#ifndef BITCOIN_KEY_H
|
||||
#define BITCOIN_KEY_H
|
||||
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
|
||||
#include <openssl/ec.h>
|
||||
#include <openssl/ecdsa.h>
|
||||
#include <openssl/obj_mac.h>
|
||||
|
||||
#include "allocators.h"
|
||||
#include "uint256.h"
|
||||
|
||||
#include <openssl/ec.h> // for EC_KEY definition
|
||||
|
||||
// secp160k1
|
||||
// const unsigned int PRIVATE_KEY_SIZE = 192;
|
||||
// const unsigned int PUBLIC_KEY_SIZE = 41;
|
||||
@@ -38,9 +36,6 @@
|
||||
// see www.keylength.com
|
||||
// script supports up to 75 for single byte push
|
||||
|
||||
int extern EC_KEY_regenerate_key(EC_KEY *eckey, BIGNUM *priv_key);
|
||||
int extern ECDSA_SIG_recover_key_GFp(EC_KEY *eckey, ECDSA_SIG *ecsig, const unsigned char *msg, int msglen, int recid, int check);
|
||||
|
||||
class key_error : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
@@ -62,267 +57,50 @@ protected:
|
||||
bool fSet;
|
||||
bool fCompressedPubKey;
|
||||
|
||||
void SetCompressedPubKey()
|
||||
{
|
||||
EC_KEY_set_conv_form(pkey, POINT_CONVERSION_COMPRESSED);
|
||||
fCompressedPubKey = true;
|
||||
}
|
||||
void SetCompressedPubKey();
|
||||
|
||||
public:
|
||||
|
||||
void Reset()
|
||||
{
|
||||
fCompressedPubKey = false;
|
||||
pkey = EC_KEY_new_by_curve_name(NID_secp256k1);
|
||||
if (pkey == NULL)
|
||||
throw key_error("CKey::CKey() : EC_KEY_new_by_curve_name failed");
|
||||
fSet = false;
|
||||
}
|
||||
void Reset();
|
||||
|
||||
CKey()
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
CKey();
|
||||
CKey(const CKey& b);
|
||||
|
||||
CKey(const CKey& b)
|
||||
{
|
||||
pkey = EC_KEY_dup(b.pkey);
|
||||
if (pkey == NULL)
|
||||
throw key_error("CKey::CKey(const CKey&) : EC_KEY_dup failed");
|
||||
fSet = b.fSet;
|
||||
}
|
||||
CKey& operator=(const CKey& b);
|
||||
|
||||
CKey& operator=(const CKey& b)
|
||||
{
|
||||
if (!EC_KEY_copy(pkey, b.pkey))
|
||||
throw key_error("CKey::operator=(const CKey&) : EC_KEY_copy failed");
|
||||
fSet = b.fSet;
|
||||
return (*this);
|
||||
}
|
||||
~CKey();
|
||||
|
||||
~CKey()
|
||||
{
|
||||
EC_KEY_free(pkey);
|
||||
}
|
||||
bool IsNull() const;
|
||||
bool IsCompressed() const;
|
||||
|
||||
bool IsNull() const
|
||||
{
|
||||
return !fSet;
|
||||
}
|
||||
void MakeNewKey(bool fCompressed);
|
||||
bool SetPrivKey(const CPrivKey& vchPrivKey);
|
||||
bool SetSecret(const CSecret& vchSecret, bool fCompressed = false);
|
||||
CSecret GetSecret(bool &fCompressed) const;
|
||||
CPrivKey GetPrivKey() const;
|
||||
bool SetPubKey(const std::vector<unsigned char>& vchPubKey);
|
||||
std::vector<unsigned char> GetPubKey() const;
|
||||
|
||||
bool IsCompressed() const
|
||||
{
|
||||
return fCompressedPubKey;
|
||||
}
|
||||
|
||||
void MakeNewKey(bool fCompressed)
|
||||
{
|
||||
if (!EC_KEY_generate_key(pkey))
|
||||
throw key_error("CKey::MakeNewKey() : EC_KEY_generate_key failed");
|
||||
if (fCompressed)
|
||||
SetCompressedPubKey();
|
||||
fSet = true;
|
||||
}
|
||||
|
||||
bool SetPrivKey(const CPrivKey& vchPrivKey)
|
||||
{
|
||||
const unsigned char* pbegin = &vchPrivKey[0];
|
||||
if (!d2i_ECPrivateKey(&pkey, &pbegin, vchPrivKey.size()))
|
||||
return false;
|
||||
fSet = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SetSecret(const CSecret& vchSecret, bool fCompressed = false)
|
||||
{
|
||||
EC_KEY_free(pkey);
|
||||
pkey = EC_KEY_new_by_curve_name(NID_secp256k1);
|
||||
if (pkey == NULL)
|
||||
throw key_error("CKey::SetSecret() : EC_KEY_new_by_curve_name failed");
|
||||
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)
|
||||
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;
|
||||
if (fCompressed || fCompressedPubKey)
|
||||
SetCompressedPubKey();
|
||||
return true;
|
||||
}
|
||||
|
||||
CSecret GetSecret(bool &fCompressed) const
|
||||
{
|
||||
CSecret vchRet;
|
||||
vchRet.resize(32);
|
||||
const BIGNUM *bn = EC_KEY_get0_private_key(pkey);
|
||||
int nBytes = BN_num_bytes(bn);
|
||||
if (bn == NULL)
|
||||
throw key_error("CKey::GetSecret() : EC_KEY_get0_private_key failed");
|
||||
int n=BN_bn2bin(bn,&vchRet[32 - nBytes]);
|
||||
if (n != nBytes)
|
||||
throw key_error("CKey::GetSecret(): BN_bn2bin failed");
|
||||
fCompressed = fCompressedPubKey;
|
||||
return vchRet;
|
||||
}
|
||||
|
||||
CPrivKey GetPrivKey() const
|
||||
{
|
||||
int nSize = i2d_ECPrivateKey(pkey, NULL);
|
||||
if (!nSize)
|
||||
throw key_error("CKey::GetPrivKey() : i2d_ECPrivateKey failed");
|
||||
CPrivKey vchPrivKey(nSize, 0);
|
||||
unsigned char* pbegin = &vchPrivKey[0];
|
||||
if (i2d_ECPrivateKey(pkey, &pbegin) != nSize)
|
||||
throw key_error("CKey::GetPrivKey() : i2d_ECPrivateKey returned unexpected size");
|
||||
return vchPrivKey;
|
||||
}
|
||||
|
||||
bool SetPubKey(const std::vector<unsigned char>& vchPubKey)
|
||||
{
|
||||
const unsigned char* pbegin = &vchPubKey[0];
|
||||
if (!o2i_ECPublicKey(&pkey, &pbegin, vchPubKey.size()))
|
||||
return false;
|
||||
fSet = true;
|
||||
if (vchPubKey.size() == 33)
|
||||
SetCompressedPubKey();
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<unsigned char> GetPubKey() const
|
||||
{
|
||||
int nSize = i2o_ECPublicKey(pkey, NULL);
|
||||
if (!nSize)
|
||||
throw key_error("CKey::GetPubKey() : i2o_ECPublicKey failed");
|
||||
std::vector<unsigned char> vchPubKey(nSize, 0);
|
||||
unsigned char* pbegin = &vchPubKey[0];
|
||||
if (i2o_ECPublicKey(pkey, &pbegin) != nSize)
|
||||
throw key_error("CKey::GetPubKey() : i2o_ECPublicKey returned unexpected size");
|
||||
return vchPubKey;
|
||||
}
|
||||
|
||||
bool Sign(uint256 hash, std::vector<unsigned char>& vchSig)
|
||||
{
|
||||
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); // Shrink to fit actual size
|
||||
return true;
|
||||
}
|
||||
bool Sign(uint256 hash, std::vector<unsigned char>& vchSig);
|
||||
|
||||
// create a compact signature (65 bytes), which allows reconstructing the used public key
|
||||
// The format is one header byte, followed by two times 32 bytes for the serialized r and s values.
|
||||
// The header byte: 0x1B = first key with even y, 0x1C = first key with odd y,
|
||||
// 0x1D = second key with even y, 0x1E = second key with odd y
|
||||
bool SignCompact(uint256 hash, std::vector<unsigned char>& vchSig)
|
||||
{
|
||||
bool fOk = false;
|
||||
ECDSA_SIG *sig = ECDSA_do_sign((unsigned char*)&hash, sizeof(hash), pkey);
|
||||
if (sig==NULL)
|
||||
return false;
|
||||
vchSig.clear();
|
||||
vchSig.resize(65,0);
|
||||
int nBitsR = BN_num_bits(sig->r);
|
||||
int nBitsS = BN_num_bits(sig->s);
|
||||
if (nBitsR <= 256 && nBitsS <= 256)
|
||||
{
|
||||
int nRecId = -1;
|
||||
for (int i=0; i<4; i++)
|
||||
{
|
||||
CKey keyRec;
|
||||
keyRec.fSet = true;
|
||||
if (fCompressedPubKey)
|
||||
keyRec.SetCompressedPubKey();
|
||||
if (ECDSA_SIG_recover_key_GFp(keyRec.pkey, sig, (unsigned char*)&hash, sizeof(hash), i, 1) == 1)
|
||||
if (keyRec.GetPubKey() == this->GetPubKey())
|
||||
{
|
||||
nRecId = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (nRecId == -1)
|
||||
throw key_error("CKey::SignCompact() : unable to construct recoverable key");
|
||||
|
||||
vchSig[0] = nRecId+27+(fCompressedPubKey ? 4 : 0);
|
||||
BN_bn2bin(sig->r,&vchSig[33-(nBitsR+7)/8]);
|
||||
BN_bn2bin(sig->s,&vchSig[65-(nBitsS+7)/8]);
|
||||
fOk = true;
|
||||
}
|
||||
ECDSA_SIG_free(sig);
|
||||
return fOk;
|
||||
}
|
||||
bool SignCompact(uint256 hash, std::vector<unsigned char>& vchSig);
|
||||
|
||||
// reconstruct public key from a compact signature
|
||||
// This is only slightly more CPU intensive than just verifying it.
|
||||
// If this function succeeds, the recovered public key is guaranteed to be valid
|
||||
// (the signature is a valid signature of the given data for that key)
|
||||
bool SetCompactSignature(uint256 hash, const std::vector<unsigned char>& vchSig)
|
||||
{
|
||||
if (vchSig.size() != 65)
|
||||
return false;
|
||||
int nV = vchSig[0];
|
||||
if (nV<27 || nV>=35)
|
||||
return false;
|
||||
ECDSA_SIG *sig = ECDSA_SIG_new();
|
||||
BN_bin2bn(&vchSig[1],32,sig->r);
|
||||
BN_bin2bn(&vchSig[33],32,sig->s);
|
||||
bool SetCompactSignature(uint256 hash, const std::vector<unsigned char>& vchSig);
|
||||
|
||||
EC_KEY_free(pkey);
|
||||
pkey = EC_KEY_new_by_curve_name(NID_secp256k1);
|
||||
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 true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Verify(uint256 hash, const std::vector<unsigned char>& vchSig)
|
||||
{
|
||||
// -1 = error, 0 = bad sig, 1 = good
|
||||
if (ECDSA_verify(0, (unsigned char*)&hash, sizeof(hash), &vchSig[0], vchSig.size(), pkey) != 1)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
bool Verify(uint256 hash, const std::vector<unsigned char>& vchSig);
|
||||
|
||||
// Verify a compact signature
|
||||
bool VerifyCompact(uint256 hash, const std::vector<unsigned char>& vchSig)
|
||||
{
|
||||
CKey key;
|
||||
if (!key.SetCompactSignature(hash, vchSig))
|
||||
return false;
|
||||
if (GetPubKey() != key.GetPubKey())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
bool VerifyCompact(uint256 hash, const std::vector<unsigned char>& vchSig);
|
||||
|
||||
bool IsValid()
|
||||
{
|
||||
if (!fSet)
|
||||
return false;
|
||||
|
||||
bool fCompr;
|
||||
CSecret secret = GetSecret(fCompr);
|
||||
CKey key2;
|
||||
key2.SetSecret(secret, fCompr);
|
||||
return GetPubKey() == key2.GetPubKey();
|
||||
}
|
||||
bool IsValid();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// 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.
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "keystore.h"
|
||||
#include "script.h"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// 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.
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
#ifndef BITCOIN_KEYSTORE_H
|
||||
#define BITCOIN_KEYSTORE_H
|
||||
|
||||
|
||||
157
src/main.cpp
157
src/main.cpp
@@ -1,7 +1,8 @@
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// 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.
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "checkpoints.h"
|
||||
#include "db.h"
|
||||
#include "net.h"
|
||||
@@ -43,7 +44,7 @@ map<uint256, CBlock*> mapOrphanBlocks;
|
||||
multimap<uint256, CBlock*> mapOrphanBlocksByPrev;
|
||||
|
||||
map<uint256, CDataStream*> mapOrphanTransactions;
|
||||
multimap<uint256, CDataStream*> mapOrphanTransactionsByPrev;
|
||||
map<uint256, map<uint256, CDataStream*> > mapOrphanTransactionsByPrev;
|
||||
|
||||
// Constant stuff for coinbase transactions we create:
|
||||
CScript COINBASE_FLAGS;
|
||||
@@ -160,17 +161,37 @@ void static ResendWalletTransactions()
|
||||
// mapOrphanTransactions
|
||||
//
|
||||
|
||||
void AddOrphanTx(const CDataStream& vMsg)
|
||||
bool AddOrphanTx(const CDataStream& vMsg)
|
||||
{
|
||||
CTransaction tx;
|
||||
CDataStream(vMsg) >> tx;
|
||||
uint256 hash = tx.GetHash();
|
||||
if (mapOrphanTransactions.count(hash))
|
||||
return;
|
||||
return false;
|
||||
|
||||
CDataStream* pvMsg = mapOrphanTransactions[hash] = new CDataStream(vMsg);
|
||||
CDataStream* pvMsg = new CDataStream(vMsg);
|
||||
|
||||
// Ignore big transactions, to avoid a
|
||||
// send-big-orphans memory exhaustion attack. If a peer has a legitimate
|
||||
// large transaction with a missing parent then we assume
|
||||
// it will rebroadcast it later, after the parent transaction(s)
|
||||
// have been mined or received.
|
||||
// 10,000 orphans, each of which is at most 5,000 bytes big is
|
||||
// at most 500 megabytes of orphans:
|
||||
if (pvMsg->size() > 5000)
|
||||
{
|
||||
printf("ignoring large orphan tx (size: %u, hash: %s)\n", pvMsg->size(), hash.ToString().substr(0,10).c_str());
|
||||
delete pvMsg;
|
||||
return false;
|
||||
}
|
||||
|
||||
mapOrphanTransactions[hash] = pvMsg;
|
||||
BOOST_FOREACH(const CTxIn& txin, tx.vin)
|
||||
mapOrphanTransactionsByPrev.insert(make_pair(txin.prevout.hash, pvMsg));
|
||||
mapOrphanTransactionsByPrev[txin.prevout.hash].insert(make_pair(hash, pvMsg));
|
||||
|
||||
printf("stored orphan tx %s (mapsz %u)\n", hash.ToString().substr(0,10).c_str(),
|
||||
mapOrphanTransactions.size());
|
||||
return true;
|
||||
}
|
||||
|
||||
void static EraseOrphanTx(uint256 hash)
|
||||
@@ -182,14 +203,9 @@ void static EraseOrphanTx(uint256 hash)
|
||||
CDataStream(*pvMsg) >> tx;
|
||||
BOOST_FOREACH(const CTxIn& txin, tx.vin)
|
||||
{
|
||||
for (multimap<uint256, CDataStream*>::iterator mi = mapOrphanTransactionsByPrev.lower_bound(txin.prevout.hash);
|
||||
mi != mapOrphanTransactionsByPrev.upper_bound(txin.prevout.hash);)
|
||||
{
|
||||
if ((*mi).second == pvMsg)
|
||||
mapOrphanTransactionsByPrev.erase(mi++);
|
||||
else
|
||||
mi++;
|
||||
}
|
||||
mapOrphanTransactionsByPrev[txin.prevout.hash].erase(hash);
|
||||
if (mapOrphanTransactionsByPrev[txin.prevout.hash].empty())
|
||||
mapOrphanTransactionsByPrev.erase(txin.prevout.hash);
|
||||
}
|
||||
delete pvMsg;
|
||||
mapOrphanTransactions.erase(hash);
|
||||
@@ -201,9 +217,7 @@ unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans)
|
||||
while (mapOrphanTransactions.size() > nMaxOrphans)
|
||||
{
|
||||
// Evict a random orphan:
|
||||
std::vector<unsigned char> randbytes(32);
|
||||
RAND_bytes(&randbytes[0], 32);
|
||||
uint256 randomhash(randbytes);
|
||||
uint256 randomhash = GetRandHash();
|
||||
map<uint256, CDataStream*>::iterator it = mapOrphanTransactions.lower_bound(randomhash);
|
||||
if (it == mapOrphanTransactions.end())
|
||||
it = mapOrphanTransactions.begin();
|
||||
@@ -718,7 +732,7 @@ bool CWalletTx::AcceptWalletTransaction(CTxDB& txdb, bool fCheckInputs)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CWalletTx::AcceptWalletTransaction()
|
||||
bool CWalletTx::AcceptWalletTransaction()
|
||||
{
|
||||
CTxDB txdb("r");
|
||||
return AcceptWalletTransaction(txdb);
|
||||
@@ -1129,17 +1143,28 @@ bool CTransaction::ConnectInputs(MapPrevTx inputs,
|
||||
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);
|
||||
|
||||
// Check for negative or overflow input values
|
||||
nValueIn += txPrev.vout[prevout.n].nValue;
|
||||
if (!MoneyRange(txPrev.vout[prevout.n].nValue) || !MoneyRange(nValueIn))
|
||||
return DoS(100, error("ConnectInputs() : txin values out of range"));
|
||||
|
||||
}
|
||||
// The first loop above does all the inexpensive checks.
|
||||
// Only if ALL inputs pass do we perform expensive ECDSA signature checks.
|
||||
// Helps prevent CPU exhaustion attacks.
|
||||
for (unsigned int i = 0; i < vin.size(); i++)
|
||||
{
|
||||
COutPoint prevout = vin[i].prevout;
|
||||
assert(inputs.count(prevout.hash) > 0);
|
||||
CTxIndex& txindex = inputs[prevout.hash].first;
|
||||
CTransaction& txPrev = inputs[prevout.hash].second;
|
||||
|
||||
// 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 (!txindex.vSpent[prevout.n].IsNull())
|
||||
return fMiner ? false : error("ConnectInputs() : %s prev tx already used at %s", GetHash().ToString().substr(0,10).c_str(), txindex.vSpent[prevout.n].ToString().c_str());
|
||||
|
||||
// Check for negative or overflow input values
|
||||
nValueIn += txPrev.vout[prevout.n].nValue;
|
||||
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.
|
||||
@@ -1489,7 +1514,9 @@ bool CBlock::SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew)
|
||||
{
|
||||
uint256 hash = GetHash();
|
||||
|
||||
txdb.TxnBegin();
|
||||
if (!txdb.TxnBegin())
|
||||
return error("SetBestChain() : TxnBegin failed");
|
||||
|
||||
if (pindexGenesisBlock == NULL && hash == hashGenesisBlock)
|
||||
{
|
||||
txdb.WriteHashBestChain(hash);
|
||||
@@ -1538,7 +1565,10 @@ bool CBlock::SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew)
|
||||
printf("SetBestChain() : ReadFromDisk failed\n");
|
||||
break;
|
||||
}
|
||||
txdb.TxnBegin();
|
||||
if (!txdb.TxnBegin()) {
|
||||
printf("SetBestChain() : TxnBegin 2 failed\n");
|
||||
break;
|
||||
}
|
||||
// errors now are not fatal, we still did a reorganisation to a new chain in a valid way
|
||||
if (!block.SetBestChainInner(txdb, pindex))
|
||||
break;
|
||||
@@ -1596,7 +1626,8 @@ bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos)
|
||||
pindexNew->bnChainWork = (pindexNew->pprev ? pindexNew->pprev->bnChainWork : 0) + pindexNew->GetBlockWork();
|
||||
|
||||
CTxDB txdb;
|
||||
txdb.TxnBegin();
|
||||
if (!txdb.TxnBegin())
|
||||
return false;
|
||||
txdb.WriteBlockIndex(CDiskBlockIndex(pindexNew));
|
||||
if (!txdb.TxnCommit())
|
||||
return false;
|
||||
@@ -1824,11 +1855,11 @@ bool CheckDiskSpace(uint64 nAdditionalBytes)
|
||||
if (nFreeBytesAvailable < (uint64)15000000 + nAdditionalBytes)
|
||||
{
|
||||
fShutdown = true;
|
||||
string strMessage = _("Warning: Disk space is low ");
|
||||
string strMessage = _("Warning: Disk space is low");
|
||||
strMiscWarning = strMessage;
|
||||
printf("*** %s\n", strMessage.c_str());
|
||||
ThreadSafeMessageBox(strMessage, "Bitcoin", wxOK | wxICON_EXCLAMATION | wxMODAL);
|
||||
QueueShutdown();
|
||||
StartShutdown();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -2354,7 +2385,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
||||
// at a time so the setAddrKnowns of the chosen nodes prevent repeats
|
||||
static uint256 hashSalt;
|
||||
if (hashSalt == 0)
|
||||
RAND_bytes((unsigned char*)&hashSalt, sizeof(hashSalt));
|
||||
hashSalt = GetRandHash();
|
||||
int64 hashAddr = addr.GetHash();
|
||||
uint256 hashRand = hashSalt ^ (hashAddr<<32) ^ ((GetTime()+hashAddr)/(24*60*60));
|
||||
hashRand = Hash(BEGIN(hashRand), END(hashRand));
|
||||
@@ -2391,6 +2422,14 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
||||
return error("message inv size() = %d", vInv.size());
|
||||
}
|
||||
|
||||
// find last block in inv vector
|
||||
unsigned int nLastBlock = (unsigned int)(-1);
|
||||
for (unsigned int nInv = 0; nInv < vInv.size(); nInv++) {
|
||||
if (vInv[vInv.size() - 1 - nInv].type == MSG_BLOCK) {
|
||||
nLastBlock = vInv.size() - 1 - nInv;
|
||||
break;
|
||||
}
|
||||
}
|
||||
CTxDB txdb("r");
|
||||
for (unsigned int nInv = 0; nInv < vInv.size(); nInv++)
|
||||
{
|
||||
@@ -2404,13 +2443,19 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
||||
if (fDebug)
|
||||
printf(" got inventory: %s %s\n", inv.ToString().c_str(), fAlreadyHave ? "have" : "new");
|
||||
|
||||
// Always request the last block in an inv bundle (even if we already have it), as it is the
|
||||
// trigger for the other side to send further invs. If we are stuck on a (very long) side chain,
|
||||
// this is necessary to connect earlier received orphan blocks to the chain again.
|
||||
if (!fAlreadyHave || (inv.type == MSG_BLOCK && nInv==vInv.size()-1))
|
||||
if (!fAlreadyHave)
|
||||
pfrom->AskFor(inv);
|
||||
if (inv.type == MSG_BLOCK && mapOrphanBlocks.count(inv.hash))
|
||||
else if (inv.type == MSG_BLOCK && mapOrphanBlocks.count(inv.hash)) {
|
||||
pfrom->PushGetBlocks(pindexBest, GetOrphanRoot(mapOrphanBlocks[inv.hash]));
|
||||
} else if (nInv == nLastBlock) {
|
||||
// In case we are on a very long side-chain, it is possible that we already have
|
||||
// the last block in an inv bundle sent in response to getblocks. Try to detect
|
||||
// this situation and push another getblocks to continue.
|
||||
std::vector<CInv> vGetData(1,inv);
|
||||
pfrom->PushGetBlocks(mapBlockIndex[inv.hash], uint256(0));
|
||||
if (fDebug)
|
||||
printf("force request: %s\n", inv.ToString().c_str());
|
||||
}
|
||||
|
||||
// Track requests for our stuff
|
||||
Inventory(inv.hash);
|
||||
@@ -2551,6 +2596,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
||||
else if (strCommand == "tx")
|
||||
{
|
||||
vector<uint256> vWorkQueue;
|
||||
vector<uint256> vEraseQueue;
|
||||
CDataStream vMsg(vRecv);
|
||||
CTxDB txdb("r");
|
||||
CTransaction tx;
|
||||
@@ -2566,37 +2612,45 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
||||
RelayMessage(inv, vMsg);
|
||||
mapAlreadyAskedFor.erase(inv);
|
||||
vWorkQueue.push_back(inv.hash);
|
||||
vEraseQueue.push_back(inv.hash);
|
||||
|
||||
// Recursively process any orphan transactions that depended on this one
|
||||
for (unsigned int i = 0; i < vWorkQueue.size(); i++)
|
||||
{
|
||||
uint256 hashPrev = vWorkQueue[i];
|
||||
for (multimap<uint256, CDataStream*>::iterator mi = mapOrphanTransactionsByPrev.lower_bound(hashPrev);
|
||||
mi != mapOrphanTransactionsByPrev.upper_bound(hashPrev);
|
||||
for (map<uint256, CDataStream*>::iterator mi = mapOrphanTransactionsByPrev[hashPrev].begin();
|
||||
mi != mapOrphanTransactionsByPrev[hashPrev].end();
|
||||
++mi)
|
||||
{
|
||||
const CDataStream& vMsg = *((*mi).second);
|
||||
CTransaction tx;
|
||||
CDataStream(vMsg) >> tx;
|
||||
CInv inv(MSG_TX, tx.GetHash());
|
||||
bool fMissingInputs2 = false;
|
||||
|
||||
if (tx.AcceptToMemoryPool(txdb, true))
|
||||
if (tx.AcceptToMemoryPool(txdb, true, &fMissingInputs2))
|
||||
{
|
||||
printf(" accepted orphan tx %s\n", inv.hash.ToString().substr(0,10).c_str());
|
||||
SyncWithWallets(tx, NULL, true);
|
||||
RelayMessage(inv, vMsg);
|
||||
mapAlreadyAskedFor.erase(inv);
|
||||
vWorkQueue.push_back(inv.hash);
|
||||
vEraseQueue.push_back(inv.hash);
|
||||
}
|
||||
else if (!fMissingInputs2)
|
||||
{
|
||||
// invalid orphan
|
||||
vEraseQueue.push_back(inv.hash);
|
||||
printf(" removed invalid orphan tx %s\n", inv.hash.ToString().substr(0,10).c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_FOREACH(uint256 hash, vWorkQueue)
|
||||
BOOST_FOREACH(uint256 hash, vEraseQueue)
|
||||
EraseOrphanTx(hash);
|
||||
}
|
||||
else if (fMissingInputs)
|
||||
{
|
||||
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
|
||||
@@ -2786,7 +2840,7 @@ bool ProcessMessages(CNode* pfrom)
|
||||
unsigned int nMessageSize = hdr.nMessageSize;
|
||||
if (nMessageSize > MAX_SIZE)
|
||||
{
|
||||
printf("ProcessMessage(%s, %u bytes) : nMessageSize > MAX_SIZE\n", strCommand.c_str(), nMessageSize);
|
||||
printf("ProcessMessages(%s, %u bytes) : nMessageSize > MAX_SIZE\n", strCommand.c_str(), nMessageSize);
|
||||
continue;
|
||||
}
|
||||
if (nMessageSize > vRecv.size())
|
||||
@@ -2802,7 +2856,7 @@ bool ProcessMessages(CNode* pfrom)
|
||||
memcpy(&nChecksum, &hash, sizeof(nChecksum));
|
||||
if (nChecksum != hdr.nChecksum)
|
||||
{
|
||||
printf("ProcessMessage(%s, %u bytes) : CHECKSUM ERROR nChecksum=%08x hdr.nChecksum=%08x\n",
|
||||
printf("ProcessMessages(%s, %u bytes) : CHECKSUM ERROR nChecksum=%08x hdr.nChecksum=%08x\n",
|
||||
strCommand.c_str(), nMessageSize, nChecksum, hdr.nChecksum);
|
||||
continue;
|
||||
}
|
||||
@@ -2827,22 +2881,22 @@ bool ProcessMessages(CNode* pfrom)
|
||||
if (strstr(e.what(), "end of data"))
|
||||
{
|
||||
// Allow exceptions from underlength message on vRecv
|
||||
printf("ProcessMessage(%s, %u bytes) : Exception '%s' caught, normally caused by a message being shorter than its stated length\n", strCommand.c_str(), nMessageSize, e.what());
|
||||
printf("ProcessMessages(%s, %u bytes) : Exception '%s' caught, normally caused by a message being shorter than its stated length\n", strCommand.c_str(), nMessageSize, e.what());
|
||||
}
|
||||
else if (strstr(e.what(), "size too large"))
|
||||
{
|
||||
// Allow exceptions from overlong size
|
||||
printf("ProcessMessage(%s, %u bytes) : Exception '%s' caught\n", strCommand.c_str(), nMessageSize, e.what());
|
||||
printf("ProcessMessages(%s, %u bytes) : Exception '%s' caught\n", strCommand.c_str(), nMessageSize, e.what());
|
||||
}
|
||||
else
|
||||
{
|
||||
PrintExceptionContinue(&e, "ProcessMessage()");
|
||||
PrintExceptionContinue(&e, "ProcessMessages()");
|
||||
}
|
||||
}
|
||||
catch (std::exception& e) {
|
||||
PrintExceptionContinue(&e, "ProcessMessage()");
|
||||
PrintExceptionContinue(&e, "ProcessMessages()");
|
||||
} catch (...) {
|
||||
PrintExceptionContinue(NULL, "ProcessMessage()");
|
||||
PrintExceptionContinue(NULL, "ProcessMessages()");
|
||||
}
|
||||
|
||||
if (!fRet)
|
||||
@@ -2862,11 +2916,12 @@ bool SendMessages(CNode* pto, bool fSendTrickle)
|
||||
if (pto->nVersion == 0)
|
||||
return true;
|
||||
|
||||
// Keep-alive ping. We send a nonce of zero because we don't use it anywhere
|
||||
// Keep-alive ping. We send a nonce of zero because we don't use it anywhere
|
||||
// right now.
|
||||
if (pto->nLastSend && GetTime() - pto->nLastSend > 30 * 60 && pto->vSend.empty()) {
|
||||
uint64 nonce = 0;
|
||||
if (pto->nVersion > BIP0031_VERSION)
|
||||
pto->PushMessage("ping", 0);
|
||||
pto->PushMessage("ping", nonce);
|
||||
else
|
||||
pto->PushMessage("ping");
|
||||
}
|
||||
@@ -2945,7 +3000,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle)
|
||||
// 1/4 of tx invs blast to all immediately
|
||||
static uint256 hashSalt;
|
||||
if (hashSalt == 0)
|
||||
RAND_bytes((unsigned char*)&hashSalt, sizeof(hashSalt));
|
||||
hashSalt = GetRandHash();
|
||||
uint256 hashRand = inv.hash ^ hashSalt;
|
||||
hashRand = Hash(BEGIN(hashRand), END(hashRand));
|
||||
bool fTrickleWait = ((hashRand & 3) != 0);
|
||||
@@ -3062,7 +3117,7 @@ void SHA256Transform(void* pstate, void* pinput, const void* pinit)
|
||||
ctx.h[i] = ((uint32_t*)pinit)[i];
|
||||
|
||||
SHA256_Update(&ctx, data, sizeof(data));
|
||||
for (int i = 0; i < 8; i++)
|
||||
for (int i = 0; i < 8; i++)
|
||||
((uint32_t*)pstate)[i] = ctx.h[i];
|
||||
}
|
||||
|
||||
@@ -3188,7 +3243,7 @@ CBlock* CreateNewBlock(CReserveKey& reservekey)
|
||||
dPriority += (double)nValueIn * nConf;
|
||||
|
||||
if (fDebug && GetBoolArg("-printpriority"))
|
||||
printf("priority nValueIn=%-12I64d nConf=%-5d dPriority=%-20.1f\n", nValueIn, nConf, dPriority);
|
||||
printf("priority nValueIn=%-12"PRI64d" nConf=%-5d dPriority=%-20.1f\n", nValueIn, nConf, dPriority);
|
||||
}
|
||||
|
||||
// Priority is sum(valuein * age) / txsize
|
||||
|
||||
17
src/main.h
17
src/main.h
@@ -1,7 +1,7 @@
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// 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.
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
#ifndef BITCOIN_MAIN_H
|
||||
#define BITCOIN_MAIN_H
|
||||
|
||||
@@ -594,7 +594,13 @@ public:
|
||||
// Read transaction
|
||||
if (fseek(filein, pos.nTxPos, SEEK_SET) != 0)
|
||||
return error("CTransaction::ReadFromDisk() : fseek failed");
|
||||
filein >> *this;
|
||||
|
||||
try {
|
||||
filein >> *this;
|
||||
}
|
||||
catch (std::exception &e) {
|
||||
return error("%s() : deserialize or I/O error", __PRETTY_FUNCTION__);
|
||||
}
|
||||
|
||||
// Return file pointer
|
||||
if (pfileRet)
|
||||
@@ -976,7 +982,12 @@ public:
|
||||
filein.nType |= SER_BLOCKHEADERONLY;
|
||||
|
||||
// Read block
|
||||
filein >> *this;
|
||||
try {
|
||||
filein >> *this;
|
||||
}
|
||||
catch (std::exception &e) {
|
||||
return error("%s() : deserialize or I/O error", __PRETTY_FUNCTION__);
|
||||
}
|
||||
|
||||
// Check the header
|
||||
if (!CheckProofOfWork(GetHash(), nBits))
|
||||
|
||||
@@ -27,7 +27,7 @@ LIBS= \
|
||||
-l ssl \
|
||||
-l crypto
|
||||
|
||||
DEFS=-D_MT -DWIN32 -D_WINDOWS -DBOOST_THREAD_USE_LIB
|
||||
DEFS=-D_MT -DWIN32 -D_WINDOWS -DBOOST_THREAD_USE_LIB -DBOOST_SPIRIT_THREADSAFE
|
||||
DEBUGFLAGS=-g
|
||||
CFLAGS=-O2 -w -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(DEFS) $(INCLUDEPATHS)
|
||||
|
||||
@@ -69,7 +69,7 @@ OBJS= \
|
||||
all: bitcoind.exe
|
||||
|
||||
obj/build.h: FORCE
|
||||
../share/genbuild.sh obj/build.h
|
||||
/bin/sh ../share/genbuild.sh obj/build.h
|
||||
version.cpp: obj/build.h
|
||||
DEFS += -DHAVE_BUILD_INFO
|
||||
|
||||
|
||||
@@ -7,12 +7,12 @@ USE_UPNP:=0
|
||||
INCLUDEPATHS= \
|
||||
-I"C:\boost-1.47.0-mgw" \
|
||||
-I"C:\db-4.8.30.NC-mgw\build_unix" \
|
||||
-I"C:\openssl-1.0.0d-mgw\include"
|
||||
-I"C:\openssl-1.0.1b-mgw\include"
|
||||
|
||||
LIBPATHS= \
|
||||
-L"C:\boost-1.47.0-mgw\stage\lib" \
|
||||
-L"C:\db-4.8.30.NC-mgw\build_unix" \
|
||||
-L"C:\openssl-1.0.0d-mgw"
|
||||
-L"C:\openssl-1.0.1b-mgw"
|
||||
|
||||
LIBS= \
|
||||
-l boost_system-mgw45-mt-s-1_47 \
|
||||
@@ -23,7 +23,7 @@ LIBS= \
|
||||
-l ssl \
|
||||
-l crypto
|
||||
|
||||
DEFS=-DWIN32 -D_WINDOWS -DBOOST_THREAD_USE_LIB
|
||||
DEFS=-DWIN32 -D_WINDOWS -DBOOST_THREAD_USE_LIB -DBOOST_SPIRIT_THREADSAFE
|
||||
DEBUGFLAGS=-g
|
||||
CFLAGS=-mthreads -O2 -w -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(DEFS) $(INCLUDEPATHS)
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ LIBS += \
|
||||
TESTDEFS += -DBOOST_TEST_DYN_LINK
|
||||
endif
|
||||
|
||||
DEFS=-DMAC_OSX -DMSG_NOSIGNAL=0
|
||||
DEFS=-DMAC_OSX -DMSG_NOSIGNAL=0 -DBOOST_SPIRIT_THREADSAFE
|
||||
|
||||
ifdef RELEASE
|
||||
# Compile for maximum compatibility and smallest size.
|
||||
@@ -106,7 +106,7 @@ all: bitcoind
|
||||
-include obj-test/*.P
|
||||
|
||||
obj/build.h: FORCE
|
||||
../share/genbuild.sh obj/build.h
|
||||
/bin/sh ../share/genbuild.sh obj/build.h
|
||||
version.cpp: obj/build.h
|
||||
DEFS += -DHAVE_BUILD_INFO
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
USE_UPNP:=0
|
||||
|
||||
DEFS=
|
||||
DEFS=-DBOOST_SPIRIT_THREADSAFE
|
||||
|
||||
DEFS += $(addprefix -I,$(CURDIR) $(CURDIR)/obj $(BOOST_INCLUDE_PATH) $(BDB_INCLUDE_PATH) $(OPENSSL_INCLUDE_PATH))
|
||||
LIBS = $(addprefix -L,$(BOOST_LIB_PATH) $(BDB_LIB_PATH) $(OPENSSL_LIB_PATH))
|
||||
@@ -116,7 +116,7 @@ all: bitcoind
|
||||
-include obj-test/*.P
|
||||
|
||||
obj/build.h: FORCE
|
||||
../share/genbuild.sh obj/build.h
|
||||
/bin/sh ../share/genbuild.sh obj/build.h
|
||||
version.cpp: obj/build.h
|
||||
DEFS += -DHAVE_BUILD_INFO
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Copyright (c) 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.
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
#ifndef BITCOIN_MRUSET_H
|
||||
#define BITCOIN_MRUSET_H
|
||||
|
||||
|
||||
76
src/net.cpp
76
src/net.cpp
@@ -1,7 +1,7 @@
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// 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.
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "irc.h"
|
||||
#include "db.h"
|
||||
@@ -35,7 +35,7 @@ void ThreadOpenAddedConnections2(void* parg);
|
||||
void ThreadMapPort2(void* parg);
|
||||
#endif
|
||||
void ThreadDNSAddressSeed2(void* parg);
|
||||
bool OpenNetworkConnection(const CAddress& addrConnect);
|
||||
bool OpenNetworkConnection(const CAddress& addrConnect, bool fUseGrant = true);
|
||||
|
||||
|
||||
|
||||
@@ -64,10 +64,7 @@ map<CInv, int64> mapAlreadyAskedFor;
|
||||
set<CNetAddr> setservAddNodeAddresses;
|
||||
CCriticalSection cs_setservAddNodeAddresses;
|
||||
|
||||
static CWaitableCriticalSection csOutbound;
|
||||
static int nOutbound = 0;
|
||||
static CConditionVariable condOutbound;
|
||||
|
||||
static CSemaphore *semOutbound = NULL;
|
||||
|
||||
unsigned short GetListenPort()
|
||||
{
|
||||
@@ -368,10 +365,6 @@ CNode* ConnectNode(CAddress addrConnect, int64 nTimeout)
|
||||
LOCK(cs_vNodes);
|
||||
vNodes.push_back(pnode);
|
||||
}
|
||||
{
|
||||
WAITABLE_LOCK(csOutbound);
|
||||
nOutbound++;
|
||||
}
|
||||
|
||||
pnode->nTimeConnected = GetTime();
|
||||
return pnode;
|
||||
@@ -517,14 +510,9 @@ void ThreadSocketHandler2(void* parg)
|
||||
// remove from vNodes
|
||||
vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
|
||||
|
||||
if (!pnode->fInbound)
|
||||
{
|
||||
WAITABLE_LOCK(csOutbound);
|
||||
nOutbound--;
|
||||
|
||||
// Connection slot(s) were removed, notify connection creator(s)
|
||||
NOTIFY(condOutbound);
|
||||
}
|
||||
if (pnode->fHasGrant)
|
||||
semOutbound->post();
|
||||
pnode->fHasGrant = false;
|
||||
|
||||
// close socket and cleanup
|
||||
pnode->CloseSocketDisconnect();
|
||||
@@ -621,7 +609,7 @@ void ThreadSocketHandler2(void* parg)
|
||||
if (nSelect == SOCKET_ERROR)
|
||||
{
|
||||
int nErr = WSAGetLastError();
|
||||
if (hSocketMax > -1)
|
||||
if (hSocketMax != INVALID_SOCKET)
|
||||
{
|
||||
printf("socket select error %d\n", nErr);
|
||||
for (unsigned int i = 0; i <= hSocketMax; i++)
|
||||
@@ -1201,7 +1189,7 @@ void ThreadOpenConnections2(void* parg)
|
||||
{
|
||||
CAddress addr(CService(strAddr, GetDefaultPort(), fAllowDNS));
|
||||
if (addr.IsValid())
|
||||
OpenNetworkConnection(addr);
|
||||
OpenNetworkConnection(addr, false);
|
||||
for (int i = 0; i < 10 && i < nLoop; i++)
|
||||
{
|
||||
Sleep(500);
|
||||
@@ -1222,13 +1210,9 @@ void ThreadOpenConnections2(void* parg)
|
||||
if (fShutdown)
|
||||
return;
|
||||
|
||||
// Limit outbound connections
|
||||
int nMaxOutbound = min(MAX_OUTBOUND_CONNECTIONS, (int)GetArg("-maxconnections", 125));
|
||||
|
||||
vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
|
||||
{
|
||||
WAITABLE_LOCK(csOutbound);
|
||||
WAIT(condOutbound, fShutdown || nOutbound < nMaxOutbound);
|
||||
}
|
||||
semOutbound->wait();
|
||||
vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
|
||||
if (fShutdown)
|
||||
return;
|
||||
@@ -1261,11 +1245,15 @@ void ThreadOpenConnections2(void* parg)
|
||||
|
||||
// Only connect to one address per a.b.?.? range.
|
||||
// Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
|
||||
int nOutbound = 0;
|
||||
set<vector<unsigned char> > setConnected;
|
||||
{
|
||||
LOCK(cs_vNodes);
|
||||
BOOST_FOREACH(CNode* pnode, vNodes)
|
||||
BOOST_FOREACH(CNode* pnode, vNodes) {
|
||||
setConnected.insert(pnode->addr.GetGroup());
|
||||
if (!pnode->fInbound)
|
||||
nOutbound++;
|
||||
}
|
||||
}
|
||||
|
||||
int64 nANow = GetAdjustedTime();
|
||||
@@ -1296,6 +1284,8 @@ void ThreadOpenConnections2(void* parg)
|
||||
|
||||
if (addrConnect.IsValid())
|
||||
OpenNetworkConnection(addrConnect);
|
||||
else
|
||||
semOutbound->post();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1358,6 +1348,7 @@ void ThreadOpenAddedConnections2(void* parg)
|
||||
}
|
||||
BOOST_FOREACH(vector<CService>& vserv, vservConnectAddresses)
|
||||
{
|
||||
semOutbound->wait();
|
||||
OpenNetworkConnection(CAddress(*(vserv.begin())));
|
||||
Sleep(500);
|
||||
if (fShutdown)
|
||||
@@ -1373,7 +1364,14 @@ void ThreadOpenAddedConnections2(void* parg)
|
||||
}
|
||||
}
|
||||
|
||||
bool OpenNetworkConnection(const CAddress& addrConnect)
|
||||
bool static ReleaseGrant(bool fUseGrant) {
|
||||
if (fUseGrant)
|
||||
semOutbound->post();
|
||||
return false;
|
||||
}
|
||||
|
||||
// only call this function when semOutbound has been waited for
|
||||
bool OpenNetworkConnection(const CAddress& addrConnect, bool fUseGrant)
|
||||
{
|
||||
//
|
||||
// Initiate outbound network connection
|
||||
@@ -1382,7 +1380,7 @@ bool OpenNetworkConnection(const CAddress& addrConnect)
|
||||
return false;
|
||||
if ((CNetAddr)addrConnect == (CNetAddr)addrLocalHost || !addrConnect.IsIPv4() ||
|
||||
FindNode((CNetAddr)addrConnect) || CNode::IsBanned(addrConnect))
|
||||
return false;
|
||||
return ReleaseGrant(fUseGrant);
|
||||
|
||||
vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
|
||||
CNode* pnode = ConnectNode(addrConnect);
|
||||
@@ -1390,7 +1388,13 @@ bool OpenNetworkConnection(const CAddress& addrConnect)
|
||||
if (fShutdown)
|
||||
return false;
|
||||
if (!pnode)
|
||||
return false;
|
||||
return ReleaseGrant(fUseGrant);
|
||||
if (pnode->fHasGrant) {
|
||||
// node already has connection grant, release the one that was passed to us
|
||||
ReleaseGrant(fUseGrant);
|
||||
} else {
|
||||
pnode->fHasGrant = fUseGrant;
|
||||
}
|
||||
pnode->fNetworkNode = true;
|
||||
|
||||
return true;
|
||||
@@ -1473,7 +1477,7 @@ void ThreadMessageHandler2(void* parg)
|
||||
vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
|
||||
Sleep(100);
|
||||
if (fRequestShutdown)
|
||||
Shutdown(NULL);
|
||||
StartShutdown();
|
||||
vnThreadsRunning[THREAD_MESSAGEHANDLER]++;
|
||||
if (fShutdown)
|
||||
return;
|
||||
@@ -1567,6 +1571,12 @@ bool BindListenPort(string& strError)
|
||||
|
||||
void StartNode(void* parg)
|
||||
{
|
||||
if (semOutbound == NULL) {
|
||||
// initialize semaphore
|
||||
int nMaxOutbound = min(MAX_OUTBOUND_CONNECTIONS, (int)GetArg("-maxconnections", 125));
|
||||
semOutbound = new CSemaphore(nMaxOutbound);
|
||||
}
|
||||
|
||||
#ifdef USE_UPNP
|
||||
#if USE_UPNP
|
||||
fUseUPnP = GetBoolArg("-upnp", true);
|
||||
@@ -1693,7 +1703,9 @@ bool StopNode()
|
||||
fShutdown = true;
|
||||
nTransactionsUpdated++;
|
||||
int64 nStart = GetTime();
|
||||
NOTIFY_ALL(condOutbound);
|
||||
if (semOutbound)
|
||||
for (int i=0; i<MAX_OUTBOUND_CONNECTIONS; i++)
|
||||
semOutbound->post();
|
||||
do
|
||||
{
|
||||
int nThreadsRunning = 0;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// 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.
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
#ifndef BITCOIN_NET_H
|
||||
#define BITCOIN_NET_H
|
||||
|
||||
@@ -127,6 +127,7 @@ public:
|
||||
bool fNetworkNode;
|
||||
bool fSuccessfullyConnected;
|
||||
bool fDisconnect;
|
||||
bool fHasGrant; // whether to call semOutbound.post() at disconnect
|
||||
protected:
|
||||
int nRefCount;
|
||||
|
||||
@@ -171,6 +172,7 @@ public:
|
||||
nVersion = 0;
|
||||
strSubVer = "";
|
||||
fClient = false; // set by version message
|
||||
fHasGrant = false;
|
||||
fInbound = fInboundIn;
|
||||
fNetworkNode = false;
|
||||
fSuccessfullyConnected = false;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// 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.
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "netbase.h"
|
||||
#include "util.h"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// 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.
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
#ifndef BITCOIN_NETBASE_H
|
||||
#define BITCOIN_NETBASE_H
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright (c) 2010 Satoshi Nakamoto
|
||||
// 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.
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
#include "ui_interface.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// 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.
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "protocol.h"
|
||||
#include "util.h"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// 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.
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef __cplusplus
|
||||
# error This header can only be compiled as C++.
|
||||
|
||||
@@ -123,11 +123,6 @@ void AddressBookPage::setModel(AddressTableModel *model)
|
||||
connect(ui->tableView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
|
||||
this, SLOT(selectionChanged()));
|
||||
|
||||
if(mode == ForSending)
|
||||
{
|
||||
// Auto-select first row when in sending mode
|
||||
ui->tableView->selectRow(0);
|
||||
}
|
||||
selectionChanged();
|
||||
}
|
||||
|
||||
|
||||
@@ -281,12 +281,14 @@ int main(int argc, char *argv[])
|
||||
#endif
|
||||
app.exec();
|
||||
|
||||
window.hide();
|
||||
window.setClientModel(0);
|
||||
window.setWalletModel(0);
|
||||
guiref = 0;
|
||||
clientmodel = 0;
|
||||
walletmodel = 0;
|
||||
}
|
||||
// Shutdown the core and it's threads, but don't exit Bitcoin-Qt here
|
||||
Shutdown(NULL);
|
||||
}
|
||||
else
|
||||
|
||||
@@ -21,9 +21,12 @@ BitcoinAddressValidator::BitcoinAddressValidator(QObject *parent) :
|
||||
QValidator::State BitcoinAddressValidator::validate(QString &input, int &pos) const
|
||||
{
|
||||
// Correction
|
||||
for(int idx=0; idx<input.size(); ++idx)
|
||||
for(int idx=0; idx<input.size();)
|
||||
{
|
||||
switch(input.at(idx).unicode())
|
||||
bool removeChar = false;
|
||||
QChar ch = input.at(idx);
|
||||
// Transform characters that are visually close
|
||||
switch(ch.unicode())
|
||||
{
|
||||
case 'l':
|
||||
case 'I':
|
||||
@@ -33,9 +36,22 @@ QValidator::State BitcoinAddressValidator::validate(QString &input, int &pos) co
|
||||
case 'O':
|
||||
input[idx] = QChar('o');
|
||||
break;
|
||||
// Qt categorizes these as "Other_Format" not "Separator_Space"
|
||||
case 0x200B: // ZERO WIDTH SPACE
|
||||
case 0xFEFF: // ZERO WIDTH NO-BREAK SPACE
|
||||
removeChar = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
// Remove whitespace
|
||||
if(ch.isSpace())
|
||||
removeChar = true;
|
||||
// To next character
|
||||
if(removeChar)
|
||||
input.remove(idx, 1);
|
||||
else
|
||||
++idx;
|
||||
}
|
||||
|
||||
// Validation
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* Qt4 bitcoin GUI.
|
||||
*
|
||||
* W.J. van der Laan 20011-2012
|
||||
* The Bitcoin Developers 20011-2012
|
||||
* W.J. van der Laan 2011-2012
|
||||
* The Bitcoin Developers 2011-2012
|
||||
*/
|
||||
#include "bitcoingui.h"
|
||||
#include "transactiontablemodel.h"
|
||||
@@ -163,8 +163,6 @@ BitcoinGUI::BitcoinGUI(QWidget *parent):
|
||||
|
||||
BitcoinGUI::~BitcoinGUI()
|
||||
{
|
||||
if(trayIcon) // Hide tray icon, as deleting will let it linger until quit (on Ubuntu)
|
||||
trayIcon->hide();
|
||||
#ifdef Q_WS_MAC
|
||||
delete appMenuBar;
|
||||
#endif
|
||||
@@ -385,7 +383,6 @@ void BitcoinGUI::createTrayIcon()
|
||||
#else
|
||||
// Note: On Mac, the dock icon is used to provide the tray's functionality.
|
||||
MacDockIconHandler *dockIconHandler = MacDockIconHandler::instance();
|
||||
connect(dockIconHandler, SIGNAL(dockIconClicked()), toggleHideAction, SLOT(trigger()));
|
||||
trayIconMenu = dockIconHandler->dockMenu();
|
||||
#endif
|
||||
|
||||
|
||||
@@ -27,8 +27,9 @@ void CSVModelWriter::addColumn(const QString &title, int column, int role)
|
||||
|
||||
static void writeValue(QTextStream &f, const QString &value)
|
||||
{
|
||||
// TODO: quoting if " or \n in string
|
||||
f << "\"" << value << "\"";
|
||||
QString escaped = value;
|
||||
escaped.replace('"', "\"\"");
|
||||
f << "\"" << escaped << "\"";
|
||||
}
|
||||
|
||||
static void writeSep(QTextStream &f)
|
||||
|
||||
@@ -28,9 +28,6 @@
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="warningLabel">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::RichText</enum>
|
||||
</property>
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
<item row="2" column="1">
|
||||
<widget class="QLabel" name="labelBalance">
|
||||
<property name="text">
|
||||
<string>123.456 BTC</string>
|
||||
<string notr="true">0 BTC</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -72,18 +72,20 @@
|
||||
<item row="3" column="1">
|
||||
<widget class="QLabel" name="labelUnconfirmed">
|
||||
<property name="text">
|
||||
<string>0 BTC</string>
|
||||
<string notr="true">0 BTC</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>11</pointsize>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string><!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;">
|
||||
<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></string>
|
||||
<string>Wallet</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
||||
@@ -213,7 +213,7 @@ MainOptionsPage::MainOptionsPage(QWidget *parent):
|
||||
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 1 kB. 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);
|
||||
|
||||
@@ -222,7 +222,6 @@ MainOptionsPage::MainOptionsPage(QWidget *parent):
|
||||
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 1 kB. Fee 0.01 recommended."));
|
||||
|
||||
fee_label->setBuddy(fee_edit);
|
||||
fee_hbox->addWidget(fee_edit);
|
||||
|
||||
@@ -150,14 +150,21 @@ WalletModel::SendCoinsReturn WalletModel::sendCoins(const QList<SendCoinsRecipie
|
||||
hex = QString::fromStdString(wtx.GetHash().GetHex());
|
||||
}
|
||||
|
||||
// Add addresses that we've sent to to the address book
|
||||
// Add addresses / update labels that we've sent to to the address book
|
||||
foreach(const SendCoinsRecipient &rcp, recipients)
|
||||
{
|
||||
std::string strAddress = rcp.address.toStdString();
|
||||
std::string strLabel = rcp.label.toStdString();
|
||||
{
|
||||
LOCK(wallet->cs_wallet);
|
||||
if (!wallet->mapAddressBook.count(strAddress))
|
||||
wallet->SetAddressBookName(strAddress, rcp.label.toStdString());
|
||||
|
||||
std::map<CBitcoinAddress, std::string>::iterator mi = wallet->mapAddressBook.find(strAddress);
|
||||
|
||||
// Check if we have a new address or an updated label
|
||||
if (mi == wallet->mapAddressBook.end() || mi->second != strLabel)
|
||||
{
|
||||
wallet->SetAddressBookName(strAddress, strLabel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// 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.
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "init.h" // for pwalletMain
|
||||
#include "bitcoinrpc.h"
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// 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.
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace boost;
|
||||
@@ -12,6 +13,7 @@ using namespace boost;
|
||||
#include "bignum.h"
|
||||
#include "key.h"
|
||||
#include "main.h"
|
||||
#include "util.h"
|
||||
|
||||
bool CheckSig(vector<unsigned char> vchSig, vector<unsigned char> vchPubKey, CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType);
|
||||
|
||||
@@ -1099,12 +1101,67 @@ uint256 SignatureHash(CScript scriptCode, const CTransaction& txTo, unsigned int
|
||||
}
|
||||
|
||||
|
||||
// Valid signature cache, to avoid doing expensive ECDSA signature checking
|
||||
// twice for every transaction (once when accepted into memory pool, and
|
||||
// again when accepted into the block chain)
|
||||
|
||||
class CSignatureCache
|
||||
{
|
||||
private:
|
||||
// sigdata_type is (signature hash, signature, public key):
|
||||
typedef boost::tuple<uint256, std::vector<unsigned char>, std::vector<unsigned char> > sigdata_type;
|
||||
std::set< sigdata_type> setValid;
|
||||
CCriticalSection cs_sigcache;
|
||||
|
||||
public:
|
||||
bool
|
||||
Get(uint256 hash, const std::vector<unsigned char>& vchSig, const std::vector<unsigned char>& pubKey)
|
||||
{
|
||||
LOCK(cs_sigcache);
|
||||
|
||||
sigdata_type k(hash, vchSig, pubKey);
|
||||
std::set<sigdata_type>::iterator mi = setValid.find(k);
|
||||
if (mi != setValid.end())
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
Set(uint256 hash, const std::vector<unsigned char>& vchSig, const std::vector<unsigned char>& pubKey)
|
||||
{
|
||||
// DoS prevention: limit cache size to less than 10MB
|
||||
// (~200 bytes per cache entry times 50,000 entries)
|
||||
// Since there are a maximum of 20,000 signature operations per block
|
||||
// 50,000 is a reasonable default.
|
||||
int64 nMaxCacheSize = GetArg("-maxsigcachesize", 50000);
|
||||
if (nMaxCacheSize <= 0) return;
|
||||
|
||||
LOCK(cs_sigcache);
|
||||
|
||||
while (static_cast<int64>(setValid.size()) > nMaxCacheSize)
|
||||
{
|
||||
// Evict a random entry. Random because that helps
|
||||
// foil would-be DoS attackers who might try to pre-generate
|
||||
// and re-use a set of valid signatures just-slightly-greater
|
||||
// than our cache size.
|
||||
uint256 randomHash = GetRandHash();
|
||||
std::vector<unsigned char> unused;
|
||||
std::set<sigdata_type>::iterator it =
|
||||
setValid.lower_bound(sigdata_type(randomHash, unused, unused));
|
||||
if (it == setValid.end())
|
||||
it = setValid.begin();
|
||||
setValid.erase(*it);
|
||||
}
|
||||
|
||||
sigdata_type k(hash, vchSig, pubKey);
|
||||
setValid.insert(k);
|
||||
}
|
||||
};
|
||||
|
||||
bool CheckSig(vector<unsigned char> vchSig, vector<unsigned char> vchPubKey, CScript scriptCode,
|
||||
const CTransaction& txTo, unsigned int nIn, int nHashType)
|
||||
{
|
||||
CKey key;
|
||||
if (!key.SetPubKey(vchPubKey))
|
||||
return false;
|
||||
static CSignatureCache signatureCache;
|
||||
|
||||
// Hash type is one byte tacked on to the end of the signature
|
||||
if (vchSig.empty())
|
||||
@@ -1115,7 +1172,20 @@ bool CheckSig(vector<unsigned char> vchSig, vector<unsigned char> vchPubKey, CSc
|
||||
return false;
|
||||
vchSig.pop_back();
|
||||
|
||||
return key.Verify(SignatureHash(scriptCode, txTo, nIn, nHashType), vchSig);
|
||||
uint256 sighash = SignatureHash(scriptCode, txTo, nIn, nHashType);
|
||||
|
||||
if (signatureCache.Get(sighash, vchSig, vchPubKey))
|
||||
return true;
|
||||
|
||||
CKey key;
|
||||
if (!key.SetPubKey(vchPubKey))
|
||||
return false;
|
||||
|
||||
if (!key.Verify(sighash, vchSig))
|
||||
return false;
|
||||
|
||||
signatureCache.Set(sighash, vchSig, vchPubKey);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// 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.
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
#ifndef H_BITCOIN_SCRIPT
|
||||
#define H_BITCOIN_SCRIPT
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// 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.
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
#ifndef BITCOIN_SERIALIZE_H
|
||||
#define BITCOIN_SERIALIZE_H
|
||||
|
||||
|
||||
@@ -15,20 +15,20 @@ BOOST_AUTO_TEST_SUITE(Checkpoints_tests)
|
||||
BOOST_AUTO_TEST_CASE(sanity)
|
||||
{
|
||||
uint256 p11111 = uint256("0x0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d");
|
||||
uint256 p140700 = uint256("0x000000000000033b512028abb90e1626d8b346fd0ed598ac0a3c371138dce2bd");
|
||||
uint256 p134444 = uint256("0x00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe");
|
||||
BOOST_CHECK(Checkpoints::CheckBlock(11111, p11111));
|
||||
BOOST_CHECK(Checkpoints::CheckBlock(140700, p140700));
|
||||
BOOST_CHECK(Checkpoints::CheckBlock(134444, p134444));
|
||||
|
||||
|
||||
// Wrong hashes at checkpoints should fail:
|
||||
BOOST_CHECK(!Checkpoints::CheckBlock(11111, p140700));
|
||||
BOOST_CHECK(!Checkpoints::CheckBlock(140700, p11111));
|
||||
BOOST_CHECK(!Checkpoints::CheckBlock(11111, p134444));
|
||||
BOOST_CHECK(!Checkpoints::CheckBlock(134444, 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::CheckBlock(11111+1, p134444));
|
||||
BOOST_CHECK(Checkpoints::CheckBlock(134444+1, p11111));
|
||||
|
||||
BOOST_CHECK(Checkpoints::GetTotalBlocksEstimate() >= 140700);
|
||||
BOOST_CHECK(Checkpoints::GetTotalBlocksEstimate() >= 134444);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
//
|
||||
// Unit tests for denial-of-service detection/prevention code
|
||||
//
|
||||
#include <algorithm>
|
||||
|
||||
#include <boost/assign/list_of.hpp> // for 'map_list_of()'
|
||||
#include <boost/date_time/posix_time/posix_time_types.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
@@ -13,10 +16,10 @@
|
||||
#include <stdint.h>
|
||||
|
||||
// Tests this internal-to-main.cpp method:
|
||||
extern void AddOrphanTx(const CDataStream& vMsg);
|
||||
extern bool AddOrphanTx(const CDataStream& vMsg);
|
||||
extern unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans);
|
||||
extern std::map<uint256, CDataStream*> mapOrphanTransactions;
|
||||
extern std::multimap<uint256, CDataStream*> mapOrphanTransactionsByPrev;
|
||||
extern std::map<uint256, std::map<uint256, CDataStream*> > mapOrphanTransactionsByPrev;
|
||||
|
||||
CService ip(uint32_t i)
|
||||
{
|
||||
@@ -57,7 +60,7 @@ BOOST_AUTO_TEST_CASE(DoS_banscore)
|
||||
BOOST_CHECK(!CNode::IsBanned(addr1));
|
||||
dummyNode1.Misbehaving(1);
|
||||
BOOST_CHECK(CNode::IsBanned(addr1));
|
||||
mapArgs["-banscore"] = "100";
|
||||
mapArgs.erase("-banscore");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(DoS_bantime)
|
||||
@@ -129,18 +132,10 @@ BOOST_AUTO_TEST_CASE(DoS_checknbits)
|
||||
|
||||
}
|
||||
|
||||
static uint256 RandomHash()
|
||||
{
|
||||
std::vector<unsigned char> randbytes(32);
|
||||
RAND_bytes(&randbytes[0], 32);
|
||||
uint256 randomhash(randbytes);
|
||||
return randomhash;
|
||||
}
|
||||
|
||||
CTransaction RandomOrphan()
|
||||
{
|
||||
std::map<uint256, CDataStream*>::iterator it;
|
||||
it = mapOrphanTransactions.lower_bound(RandomHash());
|
||||
it = mapOrphanTransactions.lower_bound(GetRandHash());
|
||||
if (it == mapOrphanTransactions.end())
|
||||
it = mapOrphanTransactions.begin();
|
||||
const CDataStream* pvMsg = it->second;
|
||||
@@ -162,7 +157,7 @@ BOOST_AUTO_TEST_CASE(DoS_mapOrphans)
|
||||
CTransaction tx;
|
||||
tx.vin.resize(1);
|
||||
tx.vin[0].prevout.n = 0;
|
||||
tx.vin[0].prevout.hash = RandomHash();
|
||||
tx.vin[0].prevout.hash = GetRandHash();
|
||||
tx.vin[0].scriptSig << OP_1;
|
||||
tx.vout.resize(1);
|
||||
tx.vout[0].nValue = 1*CENT;
|
||||
@@ -192,6 +187,32 @@ BOOST_AUTO_TEST_CASE(DoS_mapOrphans)
|
||||
AddOrphanTx(ds);
|
||||
}
|
||||
|
||||
// This really-big orphan should be ignored:
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
CTransaction txPrev = RandomOrphan();
|
||||
|
||||
CTransaction tx;
|
||||
tx.vout.resize(1);
|
||||
tx.vout[0].nValue = 1*CENT;
|
||||
tx.vout[0].scriptPubKey.SetBitcoinAddress(key.GetPubKey());
|
||||
tx.vin.resize(500);
|
||||
for (int j = 0; j < tx.vin.size(); j++)
|
||||
{
|
||||
tx.vin[j].prevout.n = j;
|
||||
tx.vin[j].prevout.hash = txPrev.GetHash();
|
||||
}
|
||||
SignSignature(keystore, txPrev, tx, 0);
|
||||
// Re-use same signature for other inputs
|
||||
// (they don't have to be valid for this test)
|
||||
for (int j = 1; j < tx.vin.size(); j++)
|
||||
tx.vin[j].scriptSig = tx.vin[0].scriptSig;
|
||||
|
||||
CDataStream ds(SER_DISK, CLIENT_VERSION);
|
||||
ds << tx;
|
||||
BOOST_CHECK(!AddOrphanTx(ds));
|
||||
}
|
||||
|
||||
// Test LimitOrphanTxSize() function:
|
||||
LimitOrphanTxSize(40);
|
||||
BOOST_CHECK(mapOrphanTransactions.size() <= 40);
|
||||
@@ -202,4 +223,92 @@ BOOST_AUTO_TEST_CASE(DoS_mapOrphans)
|
||||
BOOST_CHECK(mapOrphanTransactionsByPrev.empty());
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(DoS_checkSig)
|
||||
{
|
||||
// Test signature caching code (see key.cpp Verify() methods)
|
||||
|
||||
CKey key;
|
||||
key.MakeNewKey(true);
|
||||
CBasicKeyStore keystore;
|
||||
keystore.AddKey(key);
|
||||
|
||||
// 100 orphan transactions:
|
||||
static const int NPREV=100;
|
||||
CTransaction orphans[NPREV];
|
||||
for (int i = 0; i < NPREV; i++)
|
||||
{
|
||||
CTransaction& tx = orphans[i];
|
||||
tx.vin.resize(1);
|
||||
tx.vin[0].prevout.n = 0;
|
||||
tx.vin[0].prevout.hash = GetRandHash();
|
||||
tx.vin[0].scriptSig << OP_1;
|
||||
tx.vout.resize(1);
|
||||
tx.vout[0].nValue = 1*CENT;
|
||||
tx.vout[0].scriptPubKey.SetBitcoinAddress(key.GetPubKey());
|
||||
|
||||
CDataStream ds(SER_DISK, CLIENT_VERSION);
|
||||
ds << tx;
|
||||
AddOrphanTx(ds);
|
||||
}
|
||||
|
||||
// Create a transaction that depends on orphans:
|
||||
CTransaction tx;
|
||||
tx.vout.resize(1);
|
||||
tx.vout[0].nValue = 1*CENT;
|
||||
tx.vout[0].scriptPubKey.SetBitcoinAddress(key.GetPubKey());
|
||||
tx.vin.resize(NPREV);
|
||||
for (int j = 0; j < tx.vin.size(); j++)
|
||||
{
|
||||
tx.vin[j].prevout.n = 0;
|
||||
tx.vin[j].prevout.hash = orphans[j].GetHash();
|
||||
}
|
||||
// Creating signatures primes the cache:
|
||||
boost::posix_time::ptime mst1 = boost::posix_time::microsec_clock::local_time();
|
||||
for (int j = 0; j < tx.vin.size(); j++)
|
||||
BOOST_CHECK(SignSignature(keystore, orphans[j], tx, j));
|
||||
boost::posix_time::ptime mst2 = boost::posix_time::microsec_clock::local_time();
|
||||
boost::posix_time::time_duration msdiff = mst2 - mst1;
|
||||
long nOneValidate = msdiff.total_milliseconds();
|
||||
if (fDebug) printf("DoS_Checksig sign: %ld\n", nOneValidate);
|
||||
|
||||
// ... now validating repeatedly should be quick:
|
||||
// 2.8GHz machine, -g build: Sign takes ~760ms,
|
||||
// uncached Verify takes ~250ms, cached Verify takes ~50ms
|
||||
// (for 100 single-signature inputs)
|
||||
mst1 = boost::posix_time::microsec_clock::local_time();
|
||||
for (int i = 0; i < 5; i++)
|
||||
for (int j = 0; j < tx.vin.size(); j++)
|
||||
BOOST_CHECK(VerifySignature(orphans[j], tx, j, true, SIGHASH_ALL));
|
||||
mst2 = boost::posix_time::microsec_clock::local_time();
|
||||
msdiff = mst2 - mst1;
|
||||
long nManyValidate = msdiff.total_milliseconds();
|
||||
if (fDebug) printf("DoS_Checksig five: %ld\n", nManyValidate);
|
||||
|
||||
BOOST_CHECK_MESSAGE(nManyValidate < nOneValidate, "Signature cache timing failed");
|
||||
|
||||
// Empty a signature, validation should fail:
|
||||
CScript save = tx.vin[0].scriptSig;
|
||||
tx.vin[0].scriptSig = CScript();
|
||||
BOOST_CHECK(!VerifySignature(orphans[0], tx, 0, true, SIGHASH_ALL));
|
||||
tx.vin[0].scriptSig = save;
|
||||
|
||||
// Swap signatures, validation should fail:
|
||||
std::swap(tx.vin[0].scriptSig, tx.vin[1].scriptSig);
|
||||
BOOST_CHECK(!VerifySignature(orphans[0], tx, 0, true, SIGHASH_ALL));
|
||||
BOOST_CHECK(!VerifySignature(orphans[1], tx, 1, true, SIGHASH_ALL));
|
||||
std::swap(tx.vin[0].scriptSig, tx.vin[1].scriptSig);
|
||||
|
||||
// Exercise -maxsigcachesize code:
|
||||
mapArgs["-maxsigcachesize"] = "10";
|
||||
// Generate a new, different signature for vin[0] to trigger cache clear:
|
||||
CScript oldSig = tx.vin[0].scriptSig;
|
||||
BOOST_CHECK(SignSignature(keystore, orphans[0], tx, 0));
|
||||
BOOST_CHECK(tx.vin[0].scriptSig != oldSig);
|
||||
for (int j = 0; j < tx.vin.size(); j++)
|
||||
BOOST_CHECK(VerifySignature(orphans[j], tx, j, true, SIGHASH_ALL));
|
||||
mapArgs.erase("-maxsigcachesize");
|
||||
|
||||
LimitOrphanTxSize(0);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
||||
@@ -26,3 +26,9 @@ void Shutdown(void* parg)
|
||||
{
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void StartShutdown()
|
||||
{
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Copyright (c) 2010 Satoshi Nakamoto
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
#ifndef BITCOIN_UI_INTERFACE_H
|
||||
#define BITCOIN_UI_INTERFACE_H
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// 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.
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
#ifndef BITCOIN_UINT256_H
|
||||
#define BITCOIN_UINT256_H
|
||||
|
||||
|
||||
13
src/util.cpp
13
src/util.cpp
@@ -1,7 +1,7 @@
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// 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.
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "util.h"
|
||||
#include "strlcpy.h"
|
||||
@@ -26,6 +26,7 @@ namespace boost {
|
||||
#include <boost/interprocess/sync/interprocess_mutex.hpp>
|
||||
#include <boost/interprocess/sync/interprocess_recursive_mutex.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/thread.hpp>
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/rand.h>
|
||||
|
||||
@@ -174,6 +175,12 @@ int GetRandInt(int nMax)
|
||||
return GetRand(nMax);
|
||||
}
|
||||
|
||||
uint256 GetRandHash()
|
||||
{
|
||||
uint256 hash;
|
||||
RAND_bytes((unsigned char*)&hash, sizeof(hash));
|
||||
return hash;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -209,6 +216,8 @@ inline int OutputDebugStringF(const char* pszFormat, ...)
|
||||
if (fileout)
|
||||
{
|
||||
static bool fStartedNewLine = true;
|
||||
static boost::mutex mutexDebugLog;
|
||||
boost::mutex::scoped_lock scoped_lock(mutexDebugLog);
|
||||
|
||||
// Debug print useful for profiling
|
||||
if (fLogTimestamps && fStartedNewLine)
|
||||
@@ -843,7 +852,7 @@ boost::filesystem::path GetDefaultDataDir()
|
||||
#ifdef MAC_OSX
|
||||
// Mac
|
||||
pathRet /= "Library/Application Support";
|
||||
filesystem::create_directory(pathRet);
|
||||
fs::create_directory(pathRet);
|
||||
return pathRet / "Bitcoin";
|
||||
#else
|
||||
// Unix
|
||||
|
||||
64
src/util.h
64
src/util.h
@@ -1,7 +1,7 @@
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// 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.
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
#ifndef BITCOIN_UTIL_H
|
||||
#define BITCOIN_UTIL_H
|
||||
|
||||
@@ -23,7 +23,7 @@ typedef int pid_t; /* define for windows compatiblity */
|
||||
#include <boost/filesystem/path.hpp>
|
||||
#include <boost/interprocess/sync/interprocess_recursive_mutex.hpp>
|
||||
#include <boost/interprocess/sync/scoped_lock.hpp>
|
||||
#include <boost/interprocess/sync/interprocess_condition.hpp>
|
||||
#include <boost/interprocess/sync/interprocess_semaphore.hpp>
|
||||
#include <boost/interprocess/sync/lock_options.hpp>
|
||||
#include <boost/date_time/gregorian/gregorian_types.hpp>
|
||||
#include <boost/date_time/posix_time/posix_time_types.hpp>
|
||||
@@ -168,6 +168,7 @@ bool SetStartOnSystemStartup(bool fAutoStart);
|
||||
void ShrinkDebugFile();
|
||||
int GetRandInt(int nMax);
|
||||
uint64 GetRand(uint64 nMax);
|
||||
uint256 GetRandHash();
|
||||
int64 GetTime();
|
||||
void SetMockTime(int64 nMockTimeIn);
|
||||
int64 GetAdjustedTime();
|
||||
@@ -217,9 +218,11 @@ public:
|
||||
{
|
||||
printf("LOCKCONTENTION: %s\n", pszName);
|
||||
printf("Locker: %s:%d\n", pszFile, nLine);
|
||||
}
|
||||
#endif
|
||||
lock.lock();
|
||||
#ifdef DEBUG_LOCKCONTENTION
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -270,24 +273,10 @@ public:
|
||||
};
|
||||
|
||||
typedef CMutexLock<CCriticalSection> CCriticalBlock;
|
||||
typedef CMutexLock<CWaitableCriticalSection> CWaitableCriticalBlock;
|
||||
typedef boost::interprocess::interprocess_condition CConditionVariable;
|
||||
|
||||
/** Wait for a given condition inside a WAITABLE_CRITICAL_BLOCK */
|
||||
#define WAIT(name,condition) \
|
||||
do { while(!(condition)) { (name).wait(waitablecriticalblock.GetLock()); } } while(0)
|
||||
|
||||
/** Notify waiting threads that a condition may hold now */
|
||||
#define NOTIFY(name) \
|
||||
do { (name).notify_one(); } while(0)
|
||||
|
||||
#define NOTIFY_ALL(name) \
|
||||
do { (name).notify_all(); } while(0)
|
||||
|
||||
#define LOCK(cs) CCriticalBlock criticalblock(cs, #cs, __FILE__, __LINE__)
|
||||
#define LOCK2(cs1,cs2) CCriticalBlock criticalblock1(cs1, #cs1, __FILE__, __LINE__),criticalblock2(cs2, #cs2, __FILE__, __LINE__)
|
||||
#define TRY_LOCK(cs,name) CCriticalBlock name(cs, #cs, __FILE__, __LINE__, true)
|
||||
#define WAITABLE_LOCK(cs) CWaitableCriticalBlock waitablecriticalblock(cs, #cs, __FILE__, __LINE__)
|
||||
|
||||
#define ENTER_CRITICAL_SECTION(cs) \
|
||||
{ \
|
||||
@@ -301,6 +290,47 @@ typedef boost::interprocess::interprocess_condition CConditionVariable;
|
||||
LeaveCritical(); \
|
||||
}
|
||||
|
||||
#ifdef MAC_OSX
|
||||
// boost::interprocess::interprocess_semaphore seems to spinlock on OSX; prefer polling instead
|
||||
class CSemaphore
|
||||
{
|
||||
private:
|
||||
CCriticalSection cs;
|
||||
int val;
|
||||
|
||||
public:
|
||||
CSemaphore(int init) : val(init) {}
|
||||
|
||||
void wait() {
|
||||
do {
|
||||
{
|
||||
LOCK(cs);
|
||||
if (val>0) {
|
||||
val--;
|
||||
return;
|
||||
}
|
||||
}
|
||||
Sleep(100);
|
||||
} while(1);
|
||||
}
|
||||
|
||||
bool try_wait() {
|
||||
LOCK(cs);
|
||||
if (val>0) {
|
||||
val--;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void post() {
|
||||
LOCK(cs);
|
||||
val++;
|
||||
}
|
||||
};
|
||||
#else
|
||||
typedef boost::interprocess::interprocess_semaphore CSemaphore;
|
||||
#endif
|
||||
|
||||
inline std::string i64tostr(int64 n)
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Copyright (c) 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.
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
#include <string>
|
||||
|
||||
#include "version.h"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Copyright (c) 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.
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
#ifndef BITCOIN_VERSION_H
|
||||
#define BITCOIN_VERSION_H
|
||||
|
||||
@@ -10,10 +10,11 @@
|
||||
// client versioning
|
||||
//
|
||||
|
||||
static const int CLIENT_VERSION_MAJOR = 0;
|
||||
static const int CLIENT_VERSION_MINOR = 6;
|
||||
static const int CLIENT_VERSION_REVISION = 1;
|
||||
static const int CLIENT_VERSION_BUILD = 3;
|
||||
// These need to be macro's, as version.cpp's voodoo requires it
|
||||
#define CLIENT_VERSION_MAJOR 0
|
||||
#define CLIENT_VERSION_MINOR 6
|
||||
#define CLIENT_VERSION_REVISION 3
|
||||
#define CLIENT_VERSION_BUILD 0
|
||||
|
||||
static const int CLIENT_VERSION =
|
||||
1000000 * CLIENT_VERSION_MAJOR
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// 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.
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "wallet.h"
|
||||
#include "walletdb.h"
|
||||
@@ -242,7 +242,8 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase)
|
||||
if (fFileBacked)
|
||||
{
|
||||
pwalletdbEncryption = new CWalletDB(strWalletFile);
|
||||
pwalletdbEncryption->TxnBegin();
|
||||
if (!pwalletdbEncryption->TxnBegin())
|
||||
return false;
|
||||
pwalletdbEncryption->WriteMasterKey(nMasterKeyMaxID, kMasterKey);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// 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.
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
#ifndef BITCOIN_WALLET_H
|
||||
#define BITCOIN_WALLET_H
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// 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.
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "walletdb.h"
|
||||
#include "wallet.h"
|
||||
@@ -189,7 +189,7 @@ int CWalletDB::LoadWallet(CWallet* pwallet)
|
||||
|
||||
//// debug print
|
||||
//printf("LoadWallet %s\n", wtx.GetHash().ToString().c_str());
|
||||
//printf(" %12I64d %s %s %s\n",
|
||||
//printf(" %12"PRI64d" %s %s %s\n",
|
||||
// wtx.vout[0].nValue,
|
||||
// DateTimeStrFormat("%x %H:%M:%S", wtx.GetBlockTime()).c_str(),
|
||||
// wtx.hashBlock.ToString().substr(0,20).c_str(),
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// 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.
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
#ifndef BITCOIN_WALLETDB_H
|
||||
#define BITCOIN_WALLETDB_H
|
||||
|
||||
|
||||
Reference in New Issue
Block a user