Compare commits

...

626 Commits

Author SHA1 Message Date
Gavin Andresen
397737b913 Bump version numbers for 0.6.1rc2 2012-05-04 10:22:26 -04:00
Gregory Maxwell
1210aa435f Merge pull request #1188 from Diapolo/rem_BackupWallet_wallet_h
remove obsolete BackupWallet() entry in wallet.h
2012-05-03 06:47:16 -07:00
Philip Kaufmann
e23a121afe remove obsolete BackupWallet() entry in wallet.h 2012-05-03 11:30:52 +02:00
Wladimir J. van der Laan
e099e1568a Merge pull request #1179 from Diapolo/project-file
add bitcoin-qt.rc to OTHER_FILES (shown in Qt Creator)
2012-05-01 23:57:02 -07:00
Jeff Garzik
ca97bde8ff Merge pull request #1171 from Diapolo/fix_compiler_warn
fix 2 compiler warnings
2012-05-01 15:02:41 -07:00
Philip Kaufmann
8a6329a7ac add bitcoin-qt.rc to OTHER_FILES (shown in Qt Creator) 2012-05-01 22:26:33 +02:00
Wladimir J. van der Laan
50d710496d Merge pull request #1176 from Diapolo/project-file
fix DEPENDPATH in the project file, as json has no include sub-dir and src was in twice
2012-05-01 12:38:56 -07:00
Jeff Garzik
e19ccfa657 Merge pull request #1177 from laanwj/2012_05_remove_duplicate_securestring
remove duplicate definition of SecureString in util.h
2012-05-01 10:05:00 -07:00
Wladimir J. van der Laan
6d25b0e99a Merge pull request #1172 from Diapolo/serialize_h_rem_typedef
remove unused typedef in serialize.h
2012-05-01 09:52:38 -07:00
Wladimir J. van der Laan
3ee5f8aac3 remove duplicate definition of SecureString in util.h
SecureString was moved to allocators.h in commit 6cb6d62347
2012-05-01 18:49:50 +02:00
Philip Kaufmann
68103043ce fix DEPENDPATH in the project file, as json has no include sub-dir and src was in twice 2012-05-01 18:45:10 +02:00
Jeff Garzik
bd51e8ef8a Merge pull request #1173 from Diapolo/init_cpp_comment_upd
remove references to bitcoin-wx from comment in init.cpp
2012-05-01 08:29:10 -07:00
Philip Kaufmann
1c94f88d5e fix compiler warning "suggest parentheses around assignment used as truth
value [-Wparentheses]" in util.cpp
2012-05-01 11:41:04 +02:00
Philip Kaufmann
f8e4d43be7 fix compiler warning "suggest explicit braces to avoid ambiguous "else"
[-Wparentheses]" in net.cpp
2012-05-01 11:40:08 +02:00
Philip Kaufmann
00d971e1e7 remove references to bitcoin-wx from comment in init.cpp 2012-05-01 01:59:54 +02:00
Philip Kaufmann
810b4fad7d remove unused typedef in serialize.h 2012-05-01 01:56:47 +02:00
Gavin Andresen
be8651dde7 Check earlier for blocks with duplicate transactions. Fixes #1167 2012-04-30 11:08:07 -04:00
Wladimir J. van der Laan
ec4997d48f Merge pull request #1139 from Diapolo/messagepage
change button tooltip on sign message page for copy to clipboard...
2012-04-29 04:35:27 -07:00
Wladimir J. van der Laan
0acb1e715c Merge pull request #1163 from laanwj/2012_04_uiperformanceissue
Fix critical UI performance issue (#1154)
2012-04-29 04:34:42 -07:00
Wladimir J. van der Laan
6974aff668 Fix critical UI performance issue (#1154) 2012-04-29 13:25:05 +02:00
Gavin Andresen
0acbe31cfc Update openssl version 2012-04-27 12:45:49 -04:00
Gavin Andresen
cedcec2dec Bump win32.deps version number for new openssl 2012-04-27 11:53:11 -04:00
Gavin Andresen
2b4d7735b6 Windows build: compile against openssl 1.0.1b 2012-04-27 10:52:14 -04:00
Gavin Andresen
2c31cfc271 Bump version numbers for 0.6.1rc1 2012-04-27 10:14:33 -04:00
Gavin Andresen
dfead66eac Merge pull request #1151 from freewil/listsinceblock-blockhash
listsinceblock: rpc param blockid -> blockhash
2012-04-26 15:37:12 -07:00
Gavin Andresen
27d4b53a5c Merge pull request #1150 from gavinandresen/NOPCH
Remove unused -DNOPCH
2012-04-26 15:36:33 -07:00
Gavin Andresen
b2997dc043 Merge pull request #1152 from freewil/remove-strange-debug
remove strange debug message from listsinceblock
2012-04-26 15:36:15 -07:00
Pieter Wuille
287ce61dc2 Merge pull request #1146 from drizztbsd/posix-include
We should include netinet/in.h to use sockaddr_in (POSIX.1-2001)
2012-04-26 15:25:56 -07:00
freewil
42ce57687a remove strange debug message from listsinceblock 2012-04-26 13:12:44 -04:00
freewil
fdb204abb1 listsinceblock: rpc param blockid -> blockhash
This is more consistent with the rest of the labeling seen
by the user when accessing the rpc commands.
2012-04-26 12:48:33 -04:00
Gavin Andresen
9e71a5cd23 Define TEST_DATA_DIR so unit tests can be run from any current working directory 2012-04-26 11:20:44 -04:00
Gavin Andresen
08e663d7e2 Undo part of c2e8c8ac to fix issue#1148 2012-04-26 10:18:35 -04:00
Pieter Wuille
e1ea3ce7aa Merge pull request #1119 from sipa/fastshutdown
Make lsn_reset ("detach databases") optional and off by default.
2012-04-26 05:20:57 -07:00
Gavin Andresen
cfc45319fe Remove unused -DNOPCH 2012-04-25 19:40:44 -04:00
Pieter Wuille
83743ed681 Make lsn_reset ("detach databases") optional and off by default.
Add an option -detachdb (and entry in OptionDialog), without which no
lsn_reset is called on addr.dat and blkindex.dat. That means these
files cannot be moved to a new environment, but shutdown can be
significantly faster. The wallet file is always lsn_reset'ed.

-detachdb corresponds to the old behaviour, though it is off by
default now to speed up shutdowns.
2012-04-26 00:31:54 +02:00
Timothy Redaelli
5e9dc15360 We should include netinet/in.h to use sockaddr_in (POSIX.1-2001) 2012-04-25 14:07:24 +02:00
Jeff Garzik
c2e8c8acd8 Merge pull request #1140 from jgarzik/sign-compare
Address many more sign comparison warnings
2012-04-23 21:33:29 -07:00
Jeff Garzik
735a60698c Change signed->unsigned at 3 code sites
This resolves signed/unsigned comparison warnings.
2012-04-23 14:14:36 -04:00
Jeff Garzik
5aa0b23825 CBlock::WriteToDisk() properly checks ftell(3) for error return
Rather than storing ftell(3)'s return value -- a long -- in an
unsigned int, we store and check a properly typed temp.  Then, assured a
non-negative value, we store in nBlockPosRet.
2012-04-23 14:14:36 -04:00
Jeff Garzik
1d8c7a9557 Add casts for unavoidable signed/unsigned comparisons
At these code sites, it is preferable to cast rather than change
a variable's type.
2012-04-23 14:14:36 -04:00
Jeff Garzik
c0a0a93d02 Test ScriptSigArgsExpected() for error, before accumulating return value 2012-04-23 14:14:36 -04:00
Jeff Garzik
7bd9c3a3cf SigOp and orphan-tx constants and counts are always unsigned.
Fixes several sign-comparison warnings.
2012-04-23 14:14:03 -04:00
Pieter Wuille
ef758662c5 Merge pull request #1133 from sipa/abspath
Make GetDataDir return absolute paths
2012-04-22 14:56:03 -07:00
Jeff Garzik
faf705a42a Prefer 'unsigned int' for loop index variables tested against ::size()
C++ STL ::size() generally returns unsigned, which implies that "int idx"
style of loop variable will generate a signed-vs-unsigned comparison warning
when testing the loop exit condition "idx < blah.size()"

Update areas of the bitcoin code where loop variables may be more properly and
correctly defined as unsigned.
2012-04-22 13:22:39 -04:00
Philip Kaufmann
a2d0fcbe38 change button tooltip on sign message page for copy to clipboard as it was missleading 2012-04-22 19:02:52 +02:00
Pieter Wuille
f4203de302 Make GetDataDir return absolute paths 2012-04-22 17:38:47 +02:00
Pieter Wuille
457661f640 Merge pull request #1124 from sipa/rpcobj3
extension of #1103: encapsulate mapCommands in CRPCTable
2012-04-21 16:49:32 -07:00
Pieter Wuille
7dbe393629 Merge pull request #1131 from laanwj/2012_04_hexstr
Integrate @JoelKatz's optimized ToHex (#562) into current HexStr function
2012-04-21 16:47:02 -07:00
Pieter Wuille
d5eb41fa08 Merge pull request #1129 from laanwj/2012_04_opcodes
Add explicit numeric constant value for all opcodes
2012-04-21 16:43:31 -07:00
Gavin Andresen
febe76e316 Merge pull request #1121 from gavinandresen/scripttest
Data-driven script evaluation unit tests (rebased to fix compiler warning).
2012-04-21 16:36:41 -07:00
Gavin Andresen
8449a8788a Data-drive script evaluation unit tests. 2012-04-21 19:35:39 -04:00
Pieter Wuille
6a7a42be16 Merge pull request #1126 from drizztbsd/master
Fix build with gcc 4.7
2012-04-21 15:13:29 -07:00
Wladimir J. van der Laan
88dc2d6c6a Integrate @JoelKatz's optimized ToHex (#562) into current HexStr function 2012-04-21 20:37:50 +02:00
Wladimir J. van der Laan
b6c837cbe1 Remove no-longer used UI hints in bitcoin core
The Qt UI has its own associated structures for temporary transaction state / cache.
2012-04-21 18:21:19 +02:00
Wladimir J. van der Laan
cdcc319c2d change type of various bare chars to bool that are only used as bool (and never serialized) 2012-04-21 18:16:11 +02:00
Wladimir J. van der Laan
7be8b2ff9c Add explicit numeric constant value for all opcodes
- Easier for debugging (what opcode was 0x... again?)
- Clarifies that the opcodes are set in stone in the protocol, and signals that it is impossible to insert opcodes in between.
2012-04-21 10:34:18 +02:00
Pieter Wuille
e46704dd90 Expose CRPCTable via bitcoinrpc.h for testing 2012-04-21 01:37:34 +02:00
Pieter Wuille
9862229d4d Encapsulate mapCommands in class CRPCTable 2012-04-21 01:20:05 +02:00
Jeff Garzik
dc42bf52c1 Encapsulate RPC command dispatch in an array of CRPCCommand's 2012-04-21 01:20:05 +02:00
Wladimir J. van der Laan
00b9c0f4b2 Merge pull request #1122 from dlitz/unsigned-char-fix
Unsigned char fix & fix undefined phexdigits[255]
2012-04-20 10:18:45 -07:00
Timothy Redaelli
9553c35d89 Add missing includes. (Fix bulding under GCC 4.7) 2012-04-20 12:50:57 +02:00
Pieter Wuille
3b9e6b7820 Merge pull request #959 from rebroad/LoadBlockIndexKillable
Added ability to respond to signals during Block Loading stage.
2012-04-19 04:33:04 -07:00
R E Broadley
871c3557bf Added ability to respond to signals during Block Loading stage. 2012-04-18 12:30:24 +01:00
Dwayne C. Litzenberger
8c8e8c2e93 Fix bugs on 'unsigned char' platforms.
In ISO C++, the signedness of 'char' is undefined.  On some platforms (e.g.
ARM), 'char' is an unsigned type, but some of the code relies on 'char' being
signed (as it is on x86).  This is indicated by compiler warnings like this:

 bignum.h: In constructor 'CBigNum::CBigNum(char)':
 bignum.h:81:59: warning: comparison is always true due to limited range of data type [-Wtype-limits]

 util.cpp: In function 'bool IsHex(const string&)':
 util.cpp:427:28: warning: comparison is always false due to limited range of data type [-Wtype-limits]

In particular, IsHex erroneously returned true regardless of the input
characters, as long as the length of the string was a positive multiple of 2.

Note: For testing, it's possible using GCC to force char to be unsigned by
adding the -funsigned-char parameter to xCXXFLAGS.
2012-04-18 00:33:32 -04:00
Dwayne C. Litzenberger
a6fa147c8d Fix phexdigits[255] is undefined. 2012-04-18 00:33:32 -04:00
Wladimir J. van der Laan
ac4161e25d Merge pull request #1118 from sipa/addbreaks
Add missing breaks in optionmodel's switch case
2012-04-17 14:33:26 -07:00
Pieter Wuille
559fc3c610 Add missing breaks in optionmodel's switch case 2012-04-17 23:27:59 +02:00
Pieter Wuille
031eae7864 Merge pull request #1114 from sipa/lesssync
Reduce sync frequency for blkindex.dat
2012-04-17 14:23:31 -07:00
Pieter Wuille
0a83c0fcef Fix tests after recent refactors 2012-04-17 20:37:47 +02:00
Pieter Wuille
c23617fef3 Merge remote-tracking branch 'jgarzik/mempool' 2012-04-17 20:12:48 +02:00
Pieter Wuille
caeddc5d37 Merge pull request #1117 from sipa/deadlockfix
Fix potential deadlock
2012-04-17 11:05:02 -07:00
Pieter Wuille
1ffeb89a52 Merge pull request #1112 from sipa/saneserial
Further reduce header dependencies
2012-04-17 11:04:29 -07:00
Pieter Wuille
6b6aaa1698 Further reduce header dependencies
This commit removes the dependency of serialize.h on PROTOCOL_VERSION,
and makes this parameter required instead of implicit. This is much saner,
as it makes the places where changing a version number can have an
influence obvious.
2012-04-17 20:03:42 +02:00
Jeff Garzik
ccd65d4261 Move proto version to version.h. Reduce header deps a bit more. 2012-04-17 20:02:38 +02:00
Jeff Garzik
9eace6b113 Move CWalletDB code to new walletdb module.
In addition to standard code separation, this change opens the door
to fixing several include inter-dependencies.
2012-04-17 20:00:55 +02:00
Pieter Wuille
ed6d0b5f85 Remove headers.h 2012-04-17 20:00:55 +02:00
Gavin Andresen
b97d54355e Merge pull request #1106 from jgarzik/sign-compare
Fix many sign-comparison warnings found in bitcoin codebase
2012-04-17 10:55:56 -07:00
Gavin Andresen
e873dc654c Merge pull request #1115 from laanwj/2012_04_cleanupmisc
Delete unused, unreachable and commented code, add missing initializer
2012-04-17 10:12:33 -07:00
Pieter Wuille
c581cc16bb Fix potential deadlock
Conflict:
* cs_main in ProcessMessages() (before calling ProcessMessages)
* cs_vSend in CNode::BeginMessage
versus:
* cs_vSend in ThreadMessageHandler2 (before calling SendMessages)
* cs_main in SendMessages

Even though cs_vSend is a try_lock, if it succeeds simultaneously with
the locking of cs_main in ProcessMessages(), it could cause a deadlock.
2012-04-17 18:50:52 +02:00
Jeff Garzik
ce8c93498a main.cpp: replace tabs with spaces
Sometimes they sneak in through the 'vi' door
2012-04-17 12:31:51 -04:00
Jeff Garzik
8bff8ac079 AlreadyHave(): only hold lock during mapTransactions access 2012-04-17 12:30:00 -04:00
Wladimir J. van der Laan
7fa3ad83a9 Remove unused and unreachable code 2012-04-17 18:28:02 +02:00
Wladimir J. van der Laan
4941aad657 Add forgotten initializer 2012-04-17 18:27:55 +02:00
Pieter Wuille
8f2b50f178 Reduce sync frequency for blkindex.dat
Since auto-remove-db-logs was enabled, each time a CTxDB was closed
outside of the initial download window, it causes a checkpoint + log
cleanup. This is overkill, so reduce the sync frequency to once per
minute at most.
2012-04-17 18:27:18 +02:00
Jeff Garzik
dd21ce5f1b Merge pull request #1094 from jgarzik/already-have-locking
Locking fix for AlreadyHave()
2012-04-17 09:23:49 -07:00
Jeff Garzik
ea9627979e Bump PROTOCOL_VERSION to 60001, thereby enabling BIP31 2012-04-17 12:16:46 -04:00
Jeff Garzik
865a0c1674 Merge pull request #1081 from jgarzik/pong
BIP 0031: pong message
2012-04-17 08:51:17 -07:00
Wladimir J. van der Laan
7a5452ffb3 Merge pull request #1092 from laanwj/2012_04_sendcoins_setlabelfix
When sending coins, set label when selecting address that already has a label
2012-04-16 05:41:39 -07:00
Wladimir J. van der Laan
088a13331b Merge pull request #1091 from Diapolo/GUI-BlockDL
revert to default OS theme for progressbar (fix #1071)
2012-04-16 00:55:37 -07:00
Jeff Garzik
9fb89c26f3 Fix misc. minor sign-comparison warnings 2012-04-15 17:00:20 -04:00
Jeff Garzik
0dd710acb6 CNode's nHeaderStart may be negative, so change its type 2012-04-15 16:59:48 -04:00
Jeff Garzik
c3fad8350b serialize.h: CAutoFile's read and write may take size_t nSize 2012-04-15 16:59:09 -04:00
Jeff Garzik
3a78f82a78 Fix sign-compare warnings: netbase's Lookup* max-solutions may be unsigned 2012-04-15 16:58:32 -04:00
Jeff Garzik
c376ac359e Fix loop index var types, fixing many minor sign comparison warnings
foo.size() typically returns an unsigned integral type; make loop variables
match those types' signedness.
2012-04-15 16:52:09 -04:00
Jeff Garzik
ab9dc75a18 The string class returns string::npos, when find() fails.
Noticed when sign-comparison warnings were enabled.
2012-04-15 16:47:24 -04:00
Jeff Garzik
ca4c4c53a8 CTxMemPool: add helper methods, to reduce global mempool.mapTx accesses 2012-04-15 14:43:19 -04:00
Jeff Garzik
d01903e751 CTxMemPool: encapsulate AcceptToMemoryPool 2012-04-15 14:43:19 -04:00
Jeff Garzik
8e45ed66dd CTxMemPool: encapsulate AddToMemoryPoolUnchecked(), RemoveFromMemoryPool(),
and nPooledTx
2012-04-15 14:42:52 -04:00
Jeff Garzik
235507ae48 New class CTxMemPool, encapsulating TX memory pool data members 2012-04-15 14:41:27 -04:00
Jeff Garzik
5a701eb7ea Merge pull request #1104 from laanwj/2012_04_clang
Enable and fix most compilation warnings
2012-04-15 11:39:15 -07:00
Jeff Garzik
fced2231f8 Merge pull request #1084 from dooglus/validate_secret
importprivkey doesn't check that it is given a private key
2012-04-15 09:25:29 -07:00
Wladimir J. van der Laan
9ea8e60a0c Merge pull request #1097 from laanwj/2012_04_runawayexception
Show a message box when runaway exception happens
2012-04-15 09:22:26 -07:00
Jeff Garzik
c99ddfaa22 Merge pull request #1100 from luke-jr/qrcode_errchk
Bugfix: Check that QRcode_encodeString didn't return NULL (error)
2012-04-15 08:31:22 -07:00
Wladimir J. van der Laan
da7bbd9dfd fix warnings: suggest explicit braces to avoid ambiguous 'else' [-Wparentheses] 2012-04-15 13:40:14 +02:00
Wladimir J. van der Laan
6642ffb761 fix warnings: '&&' within '||' [-Wlogical-op-parentheses] 2012-04-15 13:40:14 +02:00
Wladimir J. van der Laan
2e120f28e0 fix warnings: delete called on 'XX' that has virtual functions but non-virtual destructor [-Wdelete-non-virtual-dtor] 2012-04-15 13:40:14 +02:00
Wladimir J. van der Laan
11cd416525 fix warnings: unused variable 'XX' [-Wunused-variable] 2012-04-15 13:40:14 +02:00
Wladimir J. van der Laan
76d8170ce8 fix warnings: enumeration values 'XX' not handled in switch [-Wswitch-enum] 2012-04-15 13:40:14 +02:00
Wladimir J. van der Laan
87207a2e08 fix warnings: 'XX' defined as a struct here but previously declared as a class [-Wmismatched-tags] 2012-04-15 13:40:14 +02:00
Wladimir J. van der Laan
8add7822ce fix warnings: array subscript is of type 'char' [-Wchar-subscripts] 2012-04-15 13:40:14 +02:00
Wladimir J. van der Laan
1f29d399f4 work around issue in boost::program_options that prevents from compiling in clang 2012-04-15 13:40:14 +02:00
Wladimir J. van der Laan
f9f625fb32 enable all warnings except invalid-offsetof, sign-compare, unused-parameter 2012-04-15 13:40:14 +02:00
Luke Dashjr
2eb665c634 Bugfix: Check that QRcode_encodeString didn't return NULL (error)
Without this, any error will segfault Bitcoin-Qt
2012-04-14 21:00:27 -04:00
Wladimir J. van der Laan
a7a0c7a1bf Show a message box when runaway exception happens
This is more clear to users than when the program simply disappears (usually during initialization). It still logs the message to the console and debug log as well.
2012-04-14 18:35:42 +02:00
Wladimir J. van der Laan
6f6f524f1a Rename make_windows_icon.py to .sh as it is a shell script (fixes #1099) 2012-04-14 18:33:19 +02:00
Jeff Garzik
22014c31e5 Merge pull request #1093 from jgarzik/tx-opt
Database micro-optimization for "tx" network message
2012-04-14 08:50:43 -07:00
Wladimir J. van der Laan
46ba858817 Merge pull request #1089 from laanwj/2012_04_translationupdate
Update translations for bitcoin core
2012-04-13 23:47:50 -07:00
Wladimir J. van der Laan
3fddc8effc Update translations for bitcoin core
- Move scripts/qt to share/qt, to clean up toplevel directories
- Update english ts file which is used to source messages for Transifex
- In extract_strings_qt.py use a glob *.h *.cpp, this is safe now that the Wx UI files are removed
2012-04-14 08:46:16 +02:00
Wladimir J. van der Laan
c1d0547cf6 Merge pull request #1096 from laanwj/2012_04_tick
Do not show green tick unless all known blocks are downloaded (fixes #921)
2012-04-13 23:27:23 -07:00
Wladimir J. van der Laan
b970067298 Do not show green tick unless all known blocks are downloaded (fixes #921) 2012-04-14 08:21:22 +02:00
Jeff Garzik
8deb9822e4 Locking fix for AlreadyHave()
Access to mapTransactions[] must be guarded by cs_mapTransactions lock.

Also, reformat long lines to make the switch statement more readable.
2012-04-13 18:24:55 -04:00
Jeff Garzik
9925d34a49 Database micro-optimization for "tx" network message
Open database once per "tx" message, rather than multiple times,
in the case of orphan transaction presence.

As a side effect, a now-unused CTransaction::AcceptToMemoryPool()
variant is removed.
2012-04-13 17:48:15 -04:00
Wladimir J. van der Laan
2d67195ed2 Set label when selecting an address that already has a label. Fixes #1080. 2012-04-13 21:08:46 +02:00
Philip Kaufmann
e72c6a1830 revert to default OS theme for progressbar / fix small glitches in bitcoingui.cpp 2012-04-13 18:25:56 +02:00
Wladimir J. van der Laan
6b8e7eefcc Add missing tooltip and key shortcut in settings dialog (#1088 without line break part) 2012-04-13 09:16:46 +02:00
Gavin Andresen
c3c203ccd9 Merge pull request #1087 from sipa/fix_1086
Fix #1086: add /testnet to passed datadir
2012-04-12 18:22:15 -07:00
Pieter Wuille
7a743148c9 Fix #1086: add /testnet to passed datadir 2012-04-13 03:11:14 +02:00
Jeff Garzik
8b09cd3a4d Replace several network protocol version numbers with named constants
stored in version.h.

Also, a minor CAddress code reformat while we're in there, fixing
some incorrect indentation.
2012-04-12 20:07:49 -04:00
Chris Moore
b3a6e613fc CBitcoinSecret::SetString() now calls IsValid() to make sure it was passed something with the correct version. 2012-04-12 13:13:08 -07:00
Gavin Andresen
b7dc02381f Merge pull request #1041 from gavinandresen/listtransactionsfix
Bug fix listtransactions from/count handling.
2012-04-12 12:20:51 -07:00
Wladimir J. van der Laan
181400c3d5 make text in about box selectable (fixes #1055) 2012-04-12 20:55:38 +02:00
Wladimir J. van der Laan
d844cb58a8 Merge pull request #1078 from Diapolo/QR-Code
QR-Code code update

Fixes problems reported on forum: https://bitcointalk.org/index.php?topic=73695.msg839804#msg839804
2012-04-12 11:38:36 -07:00
Philip Kaufmann
7261945eb5 enable wordWrap on lblQRCode / small code comment change 2012-04-12 20:34:06 +02:00
Philip Kaufmann
b1a99c3a1f limit length of generated URI to 255 chars to prevent a DoS against the QR-Code dialog 2012-04-12 20:34:06 +02:00
Philip Kaufmann
1e8c62b29c updated to reflect pull-request suggestions / renamed some GUI elements 2012-04-12 20:34:05 +02:00
Philip Kaufmann
9e0dba8c17 fixed amount part of URI in QR-Codes / removed (no label) string if we have NO label / coding style updates / removed an unused variable 2012-04-12 20:34:04 +02:00
Jeff Garzik
460b66b14b Remove obsolete Win32 AffinityBugWorkaround()
Reference miner exists for testnet-in-a-box type situations, and as a
reference.  We don't care enough about highly optimized internal
mining to keep workarounds like this.
2012-04-12 13:24:00 -04:00
Jeff Garzik
b87c0fc440 version.h: separate client, net sections. Move more constants to this file.
* move PROTOCOL_VERSION to version.h

* move CLIENT_VERSION* to version.h, make available past cpp stage

* clearly separate client, network version portions of version.h
2012-04-12 12:23:58 -04:00
Jeff Garzik
93e447b631 BIP 0031: pong message
Add a pong message that is sent in reply to a ping. It echoes back a nonce
field that is now added to the ping message. Send a nonce of zero in ping
messages.

Original author: Mike Hearn @ Google

Modified Mike's change to introduce a mild form of protocol documentation in
version.h.
2012-04-12 12:11:56 -04:00
Gavin Andresen
940e22fd81 Fix OSX build errors. 2012-04-12 11:14:46 -04:00
Wladimir J. van der Laan
4ac24cf59e Merge pull request #855 from sje397/ToggleHide
Toggle UI hide
2012-04-11 23:02:18 -07:00
Pieter Wuille
ca2c1cb446 Merge pull request #1072 from sipa/boostpaths
Use filesystem::path instead of manual string tinkering
2012-04-11 15:02:24 -07:00
Pieter Wuille
ee12c3d60c Use filesystem::path instead of manual string tinkering
Where possible, use boost::filesystem::path instead of std::string or
char* for filenames. This avoids a lot of manual string tinkering, in
favor of path::operator/.

GetDataDir is also reworked significantly, it now only keeps two cached
directory names (the network-specific data dir, and the root data dir),
which are decided through a parameter instead of pre-initialized global
variables.

Finally, remove the "upgrade from 0.1.5" case where a debug.log in the
current directory has to be removed.
2012-04-11 22:30:23 +02:00
Wladimir J. van der Laan
bcaa5f1c04 Merge pull request #1083 from laanwj/2012_04_connectionicon
Make 4th bar of connection icon green
2012-04-11 11:06:26 -07:00
Gavin Andresen
2232717cba Remove path.make_preferred() calls, and fix compiler error in bitcoinrpc RE: boost::system 2012-04-11 14:00:48 -04:00
Wladimir J. van der Laan
5ca4f13b87 by popular request, make 4th bar of connection icon green 2012-04-11 19:59:15 +02:00
Gavin Andresen
37e7e72041 Merge pull request #1077 from sipa/buildinfo
Fix build.h dependencies
2012-04-11 10:35:44 -07:00
Pieter Wuille
4577167170 Fix build.h dependencies
For Qt builds, the build.h file is moved to build/build.h. For regular
builds, it is moved to obj/build.h. This allows the Qt build to be done
in a different directory than the source, and without interfering with
other builds.
2012-04-11 14:04:42 +02:00
Pieter Wuille
5d464a4a55 Force regeneration of build.h in qmake builds 2012-04-11 02:21:29 +02:00
Pieter Wuille
702764f53b Merge pull request #1054 from sipa/buildinfo
Build identification strings
2012-04-10 13:31:12 -07:00
Wladimir J. van der Laan
b56772e5df Merge pull request #1046 from laanwj/2012_04_rpcporterror
Show error message instead of exception crash when unable to bind RPC port
2012-04-10 13:14:47 -07:00
Pieter Wuille
a20c0d0f67 Build identification strings
All client version information is moved to version.cpp, which optionally
(-DHAVE_BUILD_INFO) includes build.h. build.h is automatically generated
on supporting platforms via contrib/genbuild.sh, using git describe.

The git export-subst attribute is used to put the commit id statically
in version.cpp inside generated archives, and this value is used if no
build.h is present.

The gitian descriptors are modified to use git archive instead of a
copy, to create the src/ directory in the output. This way,
src/src/version.cpp will contain the static commit id. To prevent
gitian builds from getting the "-dirty" marker in their git-describe
generated identifiers, no touching of files or running sed on the
makefile is performed anymore. This does not seem to influence
determinism.
2012-04-10 18:16:53 +02:00
sje397
86d5634941 Toggle main window hide on tray icon click
- converted openBictoinAction to toggleHideAction
- put GUIUtil functions into a namespace instead of a class
- put window-related functions together in optionsdialog

Reasoning:
- toggle is more typical behaviour
- it's more functional
- better UX

The typical issue with toggling visibility is that when a window
is obscured by other windows but in the 'shown' state, hiding it
isn't what you want. I've added an 'isObscured' function to GUIUtil
that checks several pixels in the window to see if they are visible
on the desktop so that an obscured but shown window can be raised.

Conflicts:

	src/qt/guiutil.cpp
	src/qt/guiutil.h
2012-04-11 00:07:32 +10:00
Pieter Wuille
962e2fcdb6 Merge pull request #1070 from cardpuncher/patch-1
Trivial: added comment lines in French & Turkish
2012-04-10 03:41:09 -07:00
Pieter Wuille
1a275bac2b Merge pull request #1052 from sipa/scopedlocks
Use scoped locks instead of CRITICAL_BLOCK
2012-04-09 13:25:17 -07:00
cardpuncher
9c2c932f8c Added comment lines in French & Turkish which basically mean "Bitcoin, virtual P2P cryptocurrency". 2012-04-09 22:22:38 +03:00
Gavin Andresen
1044391135 Merge branch 'filesystem' of https://github.com/Diapolo/bitcoin 2012-04-09 10:41:59 -04:00
Pieter Wuille
f342dac1cb Do not report spurious deadlocks caused by TRY_LOCK 2012-04-09 01:59:57 +02:00
Pieter Wuille
908037fe16 Support for parametrized locks in deadlock detector 2012-04-09 01:59:57 +02:00
Pieter Wuille
f8dcd5ca6f Use scoped locks instead of CRITICAL_BLOCK 2012-04-09 01:59:46 +02:00
Gregory Maxwell
138d08c531 Merge pull request #987 from luke-jr/ipc_name_fix
Cleanup: Replace "URL" with "URI" where we aren't actually working with URLs
2012-04-06 11:22:24 -07:00
Luke Dashjr
fa2544e79f Bugfix: Replace "URL" with "URI" where we aren't actually working with URLs 2012-04-06 12:53:37 -04:00
Wladimir J. van der Laan
3e34352222 Show error message instead of exception crash when unable to bind RPC port
Fixes issue #875
2012-04-06 18:41:23 +02:00
Philip Kaufmann
42c63d3ad2 fixed small error in bitcoinrpc.cpp 2012-04-06 15:31:28 +02:00
Philip Kaufmann
36949554ab updated util.cpp to use make_preferred() 2012-04-06 15:29:20 +02:00
Philip Kaufmann
93fb7489a7 updated bitcoinrpc.cpp to use make_preferred() and removed double inclusion of boost/filesystem.hpp 2012-04-06 15:29:19 +02:00
Philip Kaufmann
9c24588e73 updated db.cpp to use make_preferred() 2012-04-06 15:29:18 +02:00
Pieter Wuille
9362da78b0 Merge pull request #1033 from sipa/wait
Condition variables instead of polling
2012-04-06 04:11:14 -07:00
Gregory Maxwell
9682087b65 Merge pull request #1051 from graingert/patch-1
Change sign message bitcoin address tooltip to "The address to sign the ...
2012-04-05 19:21:03 -07:00
graingert
f9781fc62e Change sign message bitcoin address tooltip to "The address to sign the message with" Closes #1050 2012-04-06 04:08:16 +02:00
Gavin Andresen
3acee27b14 Merge pull request #1047 from luke-jr/strlcpy_attribute
Document strlcpy.h in assets-attribution.txt since it isn't MIT-licensed
2012-04-05 16:41:20 -07:00
Luke Dashjr
7993454a92 Document strlcpy.h in assets-attribution.txt since it isn't MIT-licensed 2012-04-05 18:58:20 -04:00
Pieter Wuille
0167938c26 Merge pull request #1045 from sipa/fastblocks2
Flush on log size instead of transaction count
2012-04-05 13:02:16 -07:00
Pieter Wuille
e88ed65a39 Flush on log size instead of transaction count 2012-04-05 20:29:47 +02:00
Gavin Andresen
399ff1fe05 Merge pull request #1043 from Diapolo/misc
removed obsolete boost workaround (boost ticket #4258)
2012-04-05 07:36:23 -07:00
Gavin Andresen
895c12943b Merge pull request #1042 from gavinandresen/use_ssl_cleanup
Remove USE_SSL #define
2012-04-05 07:34:45 -07:00
Gavin Andresen
ea2cc8fc4a Merge pull request #1037 from gavinandresen/addmultisigenable
Enable addmultisigaddress RPC call for main network
2012-04-05 07:34:19 -07:00
Gavin Andresen
c7fa55bb87 Merge pull request #1036 from gavinandresen/pubsubcleanup
Remove half-implemented publish/subscribe system
2012-04-05 07:33:54 -07:00
Gavin Andresen
78494ffecc Merge pull request #1035 from gavinandresen/osxbuild
Add ifdef RELEASE to makefile.osx as the compile-for-older-macs flags
2012-04-05 07:33:00 -07:00
Gregory Maxwell
4a8d0f3b10 Merge pull request #1039 from sipa/fix_955
Fix #955: Verify status of encrypt/decrypt calls to detect failed padding
2012-04-05 06:17:05 -07:00
Philip Kaufmann
7f10522c43 removed obsolete boost workaround (boost ticket #4258) 2012-04-05 08:34:31 +02:00
Wladimir J. van der Laan
60d5ab3a16 Merge pull request #1038 from Diapolo/misc
small misc syntactic fixes
2012-04-04 22:52:34 -07:00
Gavin Andresen
5ce4c2a23a Remove USE_SSL #define 2012-04-04 21:19:27 -04:00
Gavin Andresen
723cafcbcf Bug fix listtransactions from/count handling. 2012-04-04 20:56:13 -04:00
Pieter Wuille
e5c027b49b Verify status of encrypt/decrypt calls to detect failed padding 2012-04-05 02:07:53 +02:00
Philip Kaufmann
cf8525a571 removed an unneeded space in bitcoin-qt.pro 2012-04-05 00:11:22 +02:00
Philip Kaufmann
fc42e9fae2 removed an unused / obsolete tag from bitcoin.qrc 2012-04-05 00:11:22 +02:00
Gavin Andresen
ea8c55cfd7 Enable addmultisigaddress RPC call for main network 2012-04-04 16:01:27 -04:00
Gavin Andresen
f487746ded Remove half-implemented publish/subscribe system 2012-04-04 15:56:00 -04:00
Gavin Andresen
3a8ca61bd0 Add ifdef RELEASE to makefile.osx as the compile-for-older-macs flags 2012-04-04 15:45:31 -04:00
Pieter Wuille
092631f0ba Condition variable for outbound connection slots
Keep a global counter for nOutbound, protected with its own waitable
critical section, and wait when all outbound slots are filled, rather
than polling.

This removes the (on average) 1 second delay between a lost connection
and a new connection attempt, and may speed up shutdowns.
2012-04-04 17:24:13 +02:00
Pieter Wuille
712fd182b7 Locking system overhaul, add condition variables
This commit simplifies the locking system: CCriticalSection becomes a
simple typedef for boost::interprocess::interprocess_recursive_mutex,
and CCriticalBlock and CTryCriticalBlock are replaced by a templated
CMutexLock, which wraps boost::interprocess::scoped_lock.

By making the lock type a template parameter, some critical sections
can now be changed to non-recursive locks, which support waiting via
condition variables. These are implemented in CWaitableCriticalSection
and WAITABLE_CRITICAL_BLOCK.

CWaitableCriticalSection is a wrapper for a different Boost mutex,
which supports waiting/notification via condition variables. This
should enable us to remove much of the used polling code. Important
is that this mutex is not recursive, so functions that perform the
locking must not call eachother.

Because boost::interprocess::scoped_lock does not support assigning
and copying, I had to revert to the older CRITICAL_BLOCK macros that
use a nested for loop instead of a simple if.
2012-04-04 16:21:08 +02:00
Pieter Wuille
b0a7e05a45 Merge pull request #1019 from laanwj/2012_03_uirefactor
Streamline UI ↔ Core interface
2012-04-04 05:03:07 -07:00
Wladimir J. van der Laan
cadae3588c Merge pull request #1025 from Diapolo/GUI-BlockDL
modified block DL progressbar to be more informative and precise
2012-04-04 04:36:09 -07:00
Wladimir J. van der Laan
5cccb13dad Move from noui.h / ui.h to one ui_interface.h with dummy implementation for the daemon. 2012-04-04 13:19:30 +02:00
Wladimir J. van der Laan
5a60b66a9d Use a messagebox to display the error when -server is provided without providing a rpc password 2012-04-04 09:37:26 +02:00
Wladimir J. van der Laan
7cfbe1fee4 qtui.h/noui.h interface cleanup
- rename wxMessageBox, remove redundant arguments to noui/qtui calls
- also, add flag to force blocking, modal dialog box for disk space warning etc
- clarify function naming
- no more special MessageBox needed from AppInit2, as window object is created before calling AppInit2
2012-04-04 09:37:25 +02:00
Wladimir J. van der Laan
1a3f0da922 support RPC stop and encryptwallet with UI 2012-04-04 09:35:01 +02:00
Wladimir J. van der Laan
5d7cebdadc move translation function _ to qtui.h/noui.h instead of util.h 2012-04-04 09:35:01 +02:00
Wladimir J. van der Laan
6cb6d62347 remove dependency on serialize.h and util.h for SecureString 2012-04-04 09:35:01 +02:00
Wladimir J. van der Laan
f0b5e9e116 remove unused CalledSetStatusBar and UIThreadCall notifications 2012-04-04 09:35:01 +02:00
Wladimir J. van der Laan
98e6175874 Update UI through async calls MainFrameRepaint and AddressBookRepaint instead of a timer.
- Overall, this is better design
- This fixes problems with the address book UI not updating when the address book is changed through RPC
- Move Statusbar change detection responsibility to ClientModel
2012-04-04 09:35:01 +02:00
Wladimir J. van der Laan
7e7bcce2d9 Code deduplication: make function in GUIUtil to get connection type to call object slot in GUI thread
with invokeMethod.
2012-04-04 08:46:12 +02:00
Wladimir J. van der Laan
55f69a4700 move QT_PLUGINS stuff to qt main file, where it belongs 2012-04-04 08:46:12 +02:00
Wladimir J. van der Laan
fc8c44e3d5 Merge pull request #949 from laanwj/2012_03_vc2010compilefixes
VC2010 compile fixes
2012-04-03 11:35:33 -07:00
Wladimir J. van der Laan
52d3a48128 VC2010 compile fixes 2012-04-03 20:22:41 +02:00
Gregory Maxwell
703d64469e Merge pull request #934 from luke-jr/gitian_luke
Add Luke-Jr's PGP key to gitian-downloader
2012-04-03 08:09:13 -07:00
Philip Kaufmann
853a4a81b3 clarified comment why we use an own progressbar style / included "~" in the tr() call 2012-04-03 09:42:34 +02:00
Philip Kaufmann
ec9a4904f3 changed percentage done in tooltip to float to be more precise / allowed plurals in translation for "x block(s) remaining" 2012-04-03 08:30:13 +02:00
Gregory Maxwell
3263a245bb Merge pull request #1026 from laanwj/2012_04_increase_up_to_date_time
Increase time ago of last block for "up to date" status from 30 to 90 minutes
2012-04-02 20:35:44 -07:00
Philip Kaufmann
a7a69cd07a polished code and fixed progress display (was very jerky at the end of a sync) 2012-04-02 23:51:40 +02:00
Philip Kaufmann
e9de46c436 color update for progress bar 2012-04-02 23:48:24 +02:00
Philip Kaufmann
c7c0c93172 implemented OS independent progress bar style / moved one-time functions used on the bar to a better code location 2012-04-02 23:48:23 +02:00
Philip Kaufmann
5519660a0d changed progressbar text to "~n blocks remaining" 2012-04-02 23:48:22 +02:00
Philip Kaufmann
068ed1e838 removed relative progressbar display and moved re-worked network detection code to setNumBlocks() 2012-04-02 23:48:22 +02:00
Philip Kaufmann
9ceae8acea modified block DL progressbar to be dynamic and more precise 2012-04-02 23:48:21 +02:00
Wladimir J. van der Laan
2675fe6218 Increase time ago of last block for "up to date" status from 30 to 90 minutes
It was too hyperactive.
gmaxwell: I mean that right now when the block gap goes over an hour it starts showing synchronizing. Increasing that to 90 minutes or so would make it only happen about 6.4 times per year
2012-04-02 20:37:55 +02:00
Gavin Andresen
85ea8b4f43 Merge pull request #951 from TheBlueMatt/headerslimit
Limit getheaders to a hard 2000.
2012-04-02 11:22:11 -07:00
Pieter Wuille
91c5132ab5 Merge pull request #998 from Diapolo/transactiontable
removed an ugly line break in a transaction tooltip
2012-04-02 07:19:22 -07:00
Pieter Wuille
d3f220b2c2 Merge pull request #1022 from Diapolo/fix#1020
fix for #1020
2012-04-02 07:08:14 -07:00
Pieter Wuille
fdef04e77b Merge pull request #995 from Diapolo/master
fixed typo in comment in netbase.h and bignum.h
2012-04-02 07:07:48 -07:00
Pieter Wuille
542a1380aa Merge pull request #1006 from Diapolo/tr-tray
made tray icon tooltip translatable
2012-04-02 07:07:21 -07:00
Pieter Wuille
811bde8267 Merge pull request #1018 from sipa/gpg
Updated my GPG key
2012-04-02 07:06:24 -07:00
Gavin Andresen
f3da2a88c9 Bump version to 0.6.0.99 for 0.6.1 merge window 2012-04-02 10:03:26 -04:00
Philip Kaufmann
b5271c8861 hide Delete button (only) on ReceivingTab / hide Sign message button (only) on SendingTab 2012-04-01 13:22:34 +02:00
Pieter Wuille
94e6967e98 Updated my GPG key 2012-03-31 15:39:14 +02:00
Philip Kaufmann
7e05b97229 fixed typo in comment in netbase.h and bignum.h 2012-03-30 07:44:35 +02:00
Gavin Andresen
a1c3d8f14d Merge branch 'master' of github.com:bitcoin/bitcoin 2012-03-29 15:11:04 -04:00
Gavin Andresen
f146061d24 Merge pull request #1010 from sipa/fastblocks2
Use transactions-updated as flush condition
2012-03-29 12:10:30 -07:00
Gavin Andresen
dac1888c18 Merge pull request #1008 from gavinandresen/addrworkaround
Workaround hangs when upgrading old addr.dat files
2012-03-29 12:10:08 -07:00
Pieter Wuille
25c5eca893 Use transactions-updated as flush condition
The normal checkpointing during the block chain download is reduced
to every five minutes only, but forced every 200000 updated transactions.
2012-03-29 21:00:31 +02:00
Gavin Andresen
f3f9da868e Bump version to 0.6.0rc6 2012-03-29 13:58:22 -04:00
Gavin Andresen
6293a9f87f Workaround hangs when upgrading old addr.dat files 2012-03-29 13:34:07 -04:00
Gavin Andresen
83e914c1d5 Merge pull request #1007 from gavinandresen/log_auto_remove
Auto-remove logs, and decrease logfile size to 10M
2012-03-29 10:13:42 -07:00
Gavin Andresen
94b5960ef3 Merge pull request #996 from Diapolo/tx-lang-upd
update translations from transifex
2012-03-29 06:48:01 -07:00
Gavin Andresen
9f18347034 Auto-remove logs, and decrease logfile size to 10M 2012-03-29 09:03:11 -04:00
Philip Kaufmann
3d1d5fafc1 made tray icon tooltip translatable 2012-03-29 07:59:15 +02:00
Philip Kaufmann
0b637e0b86 removed an ugly line break in a transaction tooltip for case TransactionStatus::Mature 2012-03-27 23:20:09 +02:00
Philip Kaufmann
7b2eecd428 update translations from transifex 2012-03-27 10:13:38 +02:00
Gavin Andresen
8d29329f93 Update version to 60005 (0.6.0rc5) 2012-03-26 15:42:06 -04:00
Gavin Andresen
0ccb2c4f66 Merge branch 'master' of github.com:bitcoin/bitcoin 2012-03-26 15:37:40 -04:00
Gavin Andresen
84560c41c7 Merge pull request #994 from sipa/deladdr
Use erase instead of rewrite to remove old addr entries
2012-03-26 12:35:04 -07:00
Gavin Andresen
dd675e01c4 Merge branch 'master' of github.com:bitcoin/bitcoin 2012-03-26 15:34:13 -04:00
Gavin Andresen
be4502968e Merge pull request #992 from gavinandresen/remove_wxBitcoin
Remove wxWidgets .exe during setup
2012-03-26 12:33:02 -07:00
Gavin Andresen
c698633447 Merge branch 'master' of github.com:bitcoin/bitcoin 2012-03-26 15:31:32 -04:00
Gavin Andresen
c289d95d6b Merge pull request #991 from gavinandresen/disableWinURI
Disable bitcoin: URI handling on Windows for the 0.6 release
2012-03-26 12:31:06 -07:00
Wladimir J. van der Laan
57de7cd603 Merge pull request #990 from sipa/doc
Begin doxygen-compatible comments
2012-03-26 12:27:49 -07:00
Gavin Andresen
bf5b80a8ae Merge branch 'deladdr' of https://github.com/sipa/bitcoin 2012-03-26 14:32:26 -04:00
Pieter Wuille
53cb1a49e7 Use erase instead of rewrite to remove old addr entries 2012-03-26 20:22:38 +02:00
Gavin Andresen
a56881b005 Remove wxWidgets .exe and locales during setup 2012-03-26 14:14:45 -04:00
Wladimir J. van der Laan
e9f9282bde Merge pull request #988 from Diapolo/URL-Handling
show Window, when user is clicking bitcoin: link
2012-03-26 10:58:48 -07:00
Gavin Andresen
7b90edb5a6 Disable bitcoin: URI handling on Windows for the 0.6 release 2012-03-26 12:18:24 -04:00
Pieter Wuille
6b8de05d0a Begin doxygen-compatible comments 2012-03-26 16:48:23 +02:00
Philip Kaufmann
4004b9a40b make sure Window is shown when clicking bitcoin: Links to get user attention 2012-03-26 09:19:49 +02:00
Pieter Wuille
01a196e08d Merge pull request #974 from sipa/walletupgrade
Introduce explicit -walletupgrade option
2012-03-25 19:44:52 -07:00
Pieter Wuille
59e659fcc0 Merge pull request #983 from laanwj/2012_03_removeunusedutil
Remove unused functions from util.h/util.cpp (EOM)
2012-03-25 19:31:03 -07:00
Pieter Wuille
6eb339fae4 Merge pull request #984 from sipa/youngseeds
Give DNS seeds a random age between 3 and 7 days old
2012-03-25 17:47:54 -07:00
Pieter Wuille
b3dbab33ca Merge pull request #985 from TheBlueMatt/uri
Fix URI link to bitcoin-qt.exe instead of bitcoin.exe
2012-03-25 10:32:31 -07:00
Matt Corallo
0ec76d834e Fix URI link to bitcoin-qt.exe instead of bitcoin.exe 2012-03-25 13:23:35 -04:00
Pieter Wuille
bf1afb02ca Give DNS seeds a random age between 3 and 7 days old
This speeds up initial connections with an old/large addr.dat a lot.
2012-03-25 16:06:16 +02:00
Wladimir J. van der Laan
a6aee96c7e remove unused functions from util.h/util.cpp 2012-03-25 12:33:30 +02:00
Luke Dashjr
a41957b873 Add Luke-Jr's PGP key to gitian-downloader 2012-03-22 20:32:41 -04:00
Pieter Wuille
439e1497e1 Introduce explicit -walletupgrade option
Do not automatically change the wallet format unless the user takes an
explicit action that implies an upgrade (encrypting, for now), or uses
-walletupgrade.

-walletupgrade optionally takes an integer argument: the client version
up to which upgrading is allowed. Without an argument, it is upgraded
to latest supported version. If an argument to -walletupgrade is
provided at the time the wallet is created, the new wallet will initially
not use features beyond that version.

Third, the current wallet version number is reported in getinfo.
2012-03-22 23:47:29 +01:00
Gavin Andresen
4a17e3e6b9 Merge pull request #946 from luke-jr/bugfix_rm_mingw
Move QMAKE_LIBS_QT_ENTRY adjustment to bitcoin side of build
2012-03-22 11:14:02 -07:00
Luke Dashjr
49e1501b5d Move QMAKE_LIBS_QT_ENTRY adjustment to bitcoin side of build
It could just as well be on either part of the gitian build, but to safely put it on the Qt side would require bumping the filename, and every gitian user rebuilding it.
v0.5.3.1 put it on the Bitcoin side, and this is easier to work with and keep safe, so I'm moving it.

Use `qmake MINGW_THREAD_BUGFIX=0` to disable
2012-03-22 12:46:47 -04:00
Gavin Andresen
958fe01c32 Merge branch 'checklevel' of https://github.com/sipa/bitcoin 2012-03-22 12:18:56 -04:00
Gavin Andresen
e12d131734 Merge pull request #975 from sipa/versioncheck
Check minversion before loading the rest of the wallet
2012-03-22 09:18:11 -07:00
Gavin Andresen
a6b4a11385 Merge branch 'addrman' of https://github.com/sipa/bitcoin 2012-03-22 09:19:01 -04:00
Gavin Andresen
0e894be626 Merge pull request #964 from sipa/fastblocks
Speed up block downloading
2012-03-22 06:17:44 -07:00
Gavin Andresen
e53f03172a Merge branch 'master' of github.com:bitcoin/bitcoin 2012-03-22 08:51:37 -04:00
Wladimir J. van der Laan
5cd806a03e Merge pull request #969 from laanwj/2012_03_printconsole_error
replace call to PrintConsole with call to error()
2012-03-21 23:42:20 -07:00
Pieter Wuille
ef12c2184d Check minversion before loading the rest of the wallet
When a 0.6 wallet with compressed pubkeys is created, it writes a
minversion record to prevent older clients from reading it. If the 0.5
loading it sees a key record before seeing the minversion record however,
it will fail with DB_CORRUPT instead of DB_TOO_NEW.
2012-03-22 04:59:59 +01:00
Pieter Wuille
4538e45c46 Add -checklevel and improve -checkblocks
-checkblocks now takes a numeric argument: the number of blocks that must
be verified at the end of the chain. Default is 2500, and 0 means all
blocks.

-checklevel specifies how thorough the verification must be:
0: only check whether the block exists on disk
1: verify block validity (default)
2: verify transaction index validity
3: check transaction hashes
4: check whether spent txouts were spent within the main chain
5: check whether all prevouts are marked spent
6: check whether spent txouts were spent by a valid transaction that consumes them
2012-03-22 03:19:23 +01:00
Wladimir J. van der Laan
100da73677 Fix warning about deprecated unescaped backslash 2012-03-21 22:29:33 +01:00
Gavin Andresen
8f188ece3c Remove -bip16 and -paytoscripthashtime command-line arguments 2012-03-21 15:45:58 -04:00
Wladimir J. van der Laan
4a43dfbf3e replace call to PrintConsole with call to error()
As these are equivalent functions, this cleans up the source a bit.
Also remove PrintConsole() as this was the only use.
2012-03-21 20:33:53 +01:00
Gavin Andresen
2e2c04e250 Merge pull request #947 from ali1234/master
When disconnecting a node, the receive buffer should be cleared
2012-03-21 12:24:57 -07:00
Gavin Andresen
b2fe3a5ca6 Merge pull request #948 from sipa/unstuck
Prevent stuck block download in large reorganisations
2012-03-21 12:16:28 -07:00
Nils Schneider
3979a2ee6c Merge pull request #968 from Diapolo/doc-update
updated translation process documentation
2012-03-21 10:50:08 -07:00
Philip Kaufmann
2fac1028a8 updated translation process documentation 2012-03-21 18:41:11 +01:00
Gavin Andresen
c2b1ab072c Merge pull request #965 from khorben/master
The generic UNIX Makefile builds with lots of warnings
2012-03-21 07:45:49 -07:00
Pieter Wuille
a1a0469f91 More debug output for failed reorganizations 2012-03-21 13:15:27 +01:00
Wladimir J. van der Laan
6565f4e855 Merge pull request #967 from fanquake/patch-1
Correct date
2012-03-21 00:59:50 -07:00
Michael
246c20e8a9 Correct date 2012-03-21 15:56:38 +08:00
Wladimir J. van der Laan
4046bdf18a Merge pull request #954 from Diapolo/master
language updates for source file bitcoin_en.ts + remove cs_CZ (issue #958)
2012-03-21 00:18:58 -07:00
Pieter Wuille
0aa89c08ff Prevent stuck block download in large reorganisations
In cases of very large reorganisations (hundreds of blocks), a situation
may appear where an 'inv' is sent as response to a 'getblocks', but the
last block mentioned in the inv is already known to the receiver node.
However, the supplying node uses a request for this last block as a
trigger to send the rest of the inv blocks. If it never comes, the block
chain download is stuck.

This commit makes the receiver node always request the last inv'ed block,
even if it is already known, to prevent this problem.
2012-03-21 05:09:02 +01:00
Pieter Wuille
89516bd4e0 Speed up block downloading 2012-03-21 01:32:00 +01:00
Pierre Pronchery
7868808b2f Avoid some pointless warnings while compiling 2012-03-21 00:08:19 +01:00
Gregory Maxwell
ef14236539 Merge pull request #960 from gavinandresen/issue913
Use last checkpoint instead of hard-coded 140,700. Fixes #913.
2012-03-20 14:26:32 -07:00
Gavin Andresen
eae82d8ee5 Use last checkpoint instead of hard-coded 140,700. Fixes #913. 2012-03-20 13:45:45 -04:00
p2k
3f1bb1ac78 Proper support for Growl 1.3 notifications 2012-03-20 12:54:51 -04:00
Pieter Wuille
9aa459b294 assertion in CBlock::SetBestChainInner was too strong 2012-03-20 16:41:36 +01:00
Philip Kaufmann
d6b08f6f2c remove bitcoin_cs_CZ from bitcoin.qrc and delete bitcoin_cs_CZ.ts 2012-03-20 09:07:05 +01:00
Philip Kaufmann
603061a7e5 updated english language source file via lupdate 2012-03-19 14:08:41 +01:00
Nils Schneider
4ac3eea027 Merge pull request #953 from Diapolo/master
german translation update
2012-03-19 05:13:08 -07:00
Philip Kaufmann
8afd4699e6 fixed a capitalization error in the german translation 2012-03-19 10:28:10 +01:00
Philip Kaufmann
7c4fabde60 update german translation from transifex 2012-03-19 09:21:11 +01:00
Wladimir J. van der Laan
bd9c6f88be Merge pull request #928 from jojkaart/master
Make send coins dialog honor the configured unit type even on the first attempt.
2012-03-19 01:08:43 -07:00
Matt Corallo
ecf07f2729 Limit getheaders to a hard 2000.
Previously getheaders would return any number of headers up to
2000 + the distance the locator parameter was back (which is up to
~ the number of items in the locator ^ 2).

The only client I was able to find which actually handles the headers
message is BitcoinJ, and it clearly expects no more than 2000 headers
See:
http://code.google.com/p/bitcoinj/source/browse/core/src/main/java/com/google/bitcoin/core/HeadersMessage.java#35

Additionally, the wiki clearly states that getheaders will only ever
return 2000 headers: https://en.bitcoin.it/wiki/Network#Messages
2012-03-19 00:13:15 -04:00
Gregory Maxwell
0b99d1b574 Merge pull request #931 from luke-jr/dbg_loaderr
Wallet loading diagnostic prints to debug.log
2012-03-18 20:11:09 -07:00
Joel Kaartinen
aa3d4c0221 Make the sendcoins dialog use the configured unit type, even on the first attempt. 2012-03-18 23:04:17 +02:00
Alistair Buxton
bb13d056ea When disconnecting a node, clear the received buffer so that we do
not process any already received messages.

The primary reason to do this is if a node spams hundreds of messages
and we ban them, we don't want to continue processing the rest of it.
2012-03-18 03:03:24 +00:00
Nils Schneider
840f69c582 Merge pull request #942 from Diapolo/master
updated german translation from transifex
2012-03-17 02:05:06 -07:00
Philip Kaufmann
652856fb63 update german translation from transifex 2012-03-17 00:48:03 +01:00
Gregory Maxwell
44b69cf25e Bump CLIENT_VERSION for rc4 release 2012-03-16 15:08:57 -04:00
Gregory Maxwell
fa689db37b Merge pull request #938 from TheBlueMatt/guirpcwin32
Disable running with -server on bitcoin-qt.exe as it is broken.
2012-03-16 11:32:53 -07:00
Matt Corallo
8864019f6d Fix Win32 RPC Crashes. 2012-03-16 14:28:54 -04:00
Nils Schneider
98ff031eb8 update translations from transifex 2012-03-16 19:05:25 +01:00
Nils Schneider
6c757e99f3 add shell one-liner for updating translations in bitcoin.qrc 2012-03-16 19:03:43 +01:00
Wladimir J. van der Laan
8e910c89b8 Merge pull request #941 from laanwj/2012_03_newminimizetray
Yet another attempt of a "minimize to tray" that works on all OSes
2012-03-16 08:59:43 -07:00
Wladimir J. van der Laan
08ed96d856 Yet another attempt at implementing "minimize to tray" that works on all OSes 2012-03-16 08:17:11 +01:00
Wladimir J. van der Laan
f94177367a Fix windows build in windows Qt SDK 2012-03-15 22:28:31 +01:00
Wladimir J. van der Laan
30dfc64f48 Link -lrt library on Linux
This is needed for linking on newer Linux distribs, see http://fedoraproject.org/wiki/UnderstandingDSOLinkChange
2012-03-14 07:40:41 +01:00
Gavin Andresen
e318b99d99 Bump CLIENT_VERSION for rc3 release 2012-03-13 09:31:37 -04:00
Gregory Maxwell
89cccc83f8 Merge pull request #930 from sipa/minireorg
Limit the impact of reorganisations on the database (fix #925)
2012-03-12 15:21:36 -07:00
Pieter Wuille
d68dcf741e Limit the impact of reorganisations on the database
Sometimes a new block arrives in a new chain that was already the
best valid one, but wasn't marked that way. This happens for example
when network rules change to recover after a fork.

In this case, it is not necessary to do the entire reorganisation
inside a single db commit. These can become huge, and exceed the
objects/lockers limits in bdb. This patch limits the blocks the
actual reorganisation is applied to, and adds the next blocks
afterwards in separate db transactions.
2012-03-12 20:31:56 +01:00
Luke Dashjr
3cc0624932 Print more diagnostic info for the various DB_CORRUPT conditions 2012-03-12 14:01:15 -04:00
Pieter Wuille
336ba312a6 Merge pull request #926 from gmaxwell/master
Resolves issue #922 - "wallet passphrase timeout of several years doesn't work"
2012-03-11 18:41:00 -07:00
Luke Dashjr
21e875c958 Print wallet load errors (to debug.log) 2012-03-11 17:57:47 -04:00
Gregory Maxwell
82a10c8170 Resolves issue #922 - "wallet passphrase timeout of several years doesn't work"
2^31 milliseconds is only about 25 days. Also clamps Sleep() to 10 years,
because it currently sleeps for 0 seconds when the sleep time would cross
2^31 seconds since the epoch. Hopefully boost will be fixed by 2028.
2012-03-10 17:38:37 -05:00
Pieter Wuille
4585d828b4 Merge pull request #918 from nomnombtc/patch-1
fix typo src/net.cpp
2012-03-05 14:45:30 -08:00
nomnombtc
f8c478c4fb fix typo src/net.cpp 2012-03-05 19:33:24 +01:00
Gavin Andresen
f2e81bad33 Merge pull request #915 from sipa/nooverwritetx
Do not allow overwriting unspent transactions
2012-03-03 09:41:41 -08:00
Pieter Wuille
a206b0ea12 Do not allow overwriting unspent transactions (BIP 30)
Introduce the following network rule:
 * a block is not valid if it contains a transaction whose hash
   already exists in the block chain, unless all that transaction's
   outputs were already spent before said block.

Warning: this is effectively a network rule change, with potential
risk for forking the block chain. Leaving this unfixed carries the
same risk however, for attackers that can cause a reorganisation
in part of the network.

Thanks to Russell O'Connor and Ben Reeves.
2012-03-03 18:26:36 +01:00
Gavin Andresen
50abb5516d Updated Mac build process 2012-02-29 21:04:56 -05:00
Gavin Andresen
038fedccab Merge pull request #912 from TheBlueMatt/master
Fix release-process.txt for new deps zip.
2012-02-29 13:17:19 -08:00
Matt Corallo
95486d5c48 Fix release-process.txt for new deps zip. 2012-02-29 16:12:36 -05:00
Gavin Andresen
142e604184 DoS fix for mapOrphanTransactions 2012-02-29 11:46:46 -05:00
Gavin Andresen
722d9387be Merge branch 'mruinventory' of https://github.com/sipa/bitcoin 2012-02-28 11:48:44 -05:00
Gavin Andresen
6dd5ae41ac Merge branch '2012_02_getspecialfolderpath_overflow' of https://github.com/laanwj/bitcoin 2012-02-28 11:45:14 -05:00
Pieter Wuille
d8a80af84a Merge pull request #910 from fanquake/master
Correct Spelling
2012-02-28 04:33:43 -08:00
Michael Ford
27adfb2e0c "February" 2012-02-28 20:31:56 +08:00
Gavin Andresen
07ed49a472 Do not start bitcoin: thread on OSX. fixes #889 2012-02-27 16:08:08 -05:00
Gavin Andresen
21503e4556 Merge branch 'nodosbip16' of https://github.com/sipa/bitcoin 2012-02-27 15:47:27 -05:00
Pieter Wuille
c4341fa6ab Add mruset and use it for setInventoryKnown 2012-02-27 21:04:32 +01:00
Gavin Andresen
46aa2a6bdd Move BIP16 switchover time to April 1 2012-02-27 11:41:20 -05:00
Gavin Andresen
90d78142c0 Merge branch 'nooptionsinwallet+fixproxysetting' of https://github.com/sipa/bitcoin 2012-02-27 11:30:05 -05:00
Wladimir J. van der Laan
fbbd42a535 Merge pull request #853 from laanwj/2012_02_altminimizetray
Yet another alternative "minimize to tray" implementation

Fixes problems with window positioning.
2012-02-26 22:27:25 -08:00
Pieter Wuille
42c8b56f62 Store addrProxy port in settings 2012-02-26 23:39:32 +01:00
Gavin Andresen
3f8cb2c565 Reworked QT settings 2012-02-26 23:38:28 +01:00
Gavin Andresen
972060ce0e bitcoind changes to stop storing settings in wallet.dat. 2012-02-26 23:21:33 +01:00
Wladimir J. van der Laan
21ae37d215 Simplify MyGetSpecialFolderPath and fix possible buffer overflow (#901) 2012-02-26 17:11:38 +01:00
Wladimir J. van der Laan
3d2b5c53cb Merge pull request #900 from sipa/movebackupmenu
Move 'Backup Wallet' to file menu
2012-02-26 07:13:58 -08:00
Pieter Wuille
88c41c43ea Move 'Backup Wallet' to file menu 2012-02-26 03:04:25 +01:00
Pieter Wuille
4a10d4c6dc Fix addrProxy setting
Before 0.6 addrProxy was a CAddress, but netbase changed it to CService.
Retain compatibility by wrapping/unwrapping with a CAddress when saving
or loading.

This commit retains compatibility with 0.6.0rc1 (which wrote the setting
as a CService) by trying to parse twice.
2012-02-25 21:13:34 +01:00
Wladimir J. van der Laan
da9ab62fb7 Merge pull request #897 from laanwj/2012_02_fixnegativesecs
In UI, handle cases in which the last received block was generated in the future
2012-02-25 10:14:37 -08:00
Wladimir J. van der Laan
71ba9abba6 In UI, handle cases in which the last received block was generated in the future (secs<0)
Fixes #874.
2012-02-25 19:11:25 +01:00
Pieter Wuille
db9f2e0117 Do not invoke anti-DoS system for invalid BIP16 transactions
Doing so would allow an attack on old nodes, which would relay a
standard transaction spending a BIP16 output in an invalid way,
until reaching a new node, which will disconnect their peer.

Reported by makomk on IRC.
2012-02-25 19:05:50 +01:00
Wladimir J. van der Laan
1168d30b0a Merge pull request #894 from dooglus/nosplash
Add option "-splash" so we can disable the splash screen.
2012-02-24 23:51:50 -08:00
Chris Moore
ec4efde40c Add option "-splash" so we can disable the splash screen.
Don't show splash screen when -min is specified on the command line.
2012-02-24 19:17:22 -08:00
Pieter Wuille
5fee401fe1 CAddrMan: stochastic address manager
Design goals:
 * Only keep a limited number of addresses around, so that addr.dat does not grow without bound.
 * Keep the address tables in-memory, and occasionally write the table to addr.dat.
 * Make sure no (localized) attacker can fill the entire table with his nodes/addresses.

See comments in addrman.h for more detailed information.
2012-02-24 13:41:04 +01:00
Gavin Andresen
8c12851ed4 Checkpoint block 168,000 2012-02-23 13:33:30 -05:00
Gavin Andresen
fc4f4c2e9a Merge branch 'getblock_cleanup' of https://github.com/luke-jr/bitcoin 2012-02-23 12:41:26 -05:00
Pieter Wuille
35b327a520 Merge pull request #887 from TheBlueMatt/gitian_deps
Make deps build deterministic and upgrade to libpng 1.5.9.
2012-02-23 04:08:08 -08:00
Matt Corallo
3d0a0a9b9e Make deps build deterministic and upgrade to libpng 1.5.9. 2012-02-22 22:09:06 -05:00
Luke Dashjr
34f8788915 Cleanup JSON-RPC getblock output to be consistent
- Add "size" and "bits"
- Rename "blockcount" to "height"
- Rename "hashprevious" and "hashnext" to "previousblockhash" and "nextblockhash" (respectively)
2012-02-22 12:31:28 -05:00
Gavin Andresen
5c03282521 Merge branch 'testnetirc' of https://github.com/sipa/bitcoin 2012-02-22 11:26:19 -05:00
Gavin Andresen
6fe8c45375 Merge branch 'fixnullpfrom' of https://github.com/sipa/bitcoin 2012-02-22 11:25:08 -05:00
Gavin Andresen
e7e6ae2104 Merge branch 'postfeb20' of https://github.com/sipa/bitcoin 2012-02-22 11:06:44 -05:00
Gavin Andresen
8c7358e1dd Merge branch 'reorginfo' of https://github.com/sipa/bitcoin 2012-02-22 11:03:19 -05:00
Gavin Andresen
e1bad25fee Merge branch 'fix_616' of https://github.com/sipa/bitcoin 2012-02-22 11:00:38 -05:00
Gavin Andresen
de737806b5 Merge branch 'fix_626' of https://github.com/sipa/bitcoin 2012-02-22 10:52:14 -05:00
Gavin Andresen
1af97c95f3 Merge branch 'bugfix_bip14_ez' of https://github.com/luke-jr/bitcoin 2012-02-22 10:44:44 -05:00
Gavin Andresen
f246fc648a Merge branch '201202_guiaddsuffix' of https://github.com/laanwj/bitcoin 2012-02-22 10:41:11 -05:00
Luke Dashjr
c170d03e03 Bugfix: Instead of reporting "bitcoin-qt" for both bitcoind and Bitcoin-Qt, report "Satoshi" which is at least correct 2012-02-22 10:36:19 -05:00
Pieter Wuille
92d5864b80 Leave IRC enabled by default on testnet
As testnet has neither DNS seeds or built-in seed addresses to
bootstrap from.
2012-02-22 05:19:09 +01:00
Pieter Wuille
18c0fa97d0 Post-feb20 simplifications
Now the entire network upgraded to (initial) protocol version 209,
crtainl simplifications in the source code are possible.
2012-02-21 20:46:39 +01:00
Pieter Wuille
73aa0421a7 ProcessBlock is sometimes called with pfrom==NULL 2012-02-20 22:35:08 +01:00
Pieter Wuille
0d56f11ada Fix tests after 38067c18 2012-02-20 18:32:33 +01:00
Wladimir J. van der Laan
f7b8f824de Merge pull request #857 from laanwj/2012_02_fixhelpwindow
On windows, show message box with help, as there is no stderr (fixes #702)
2012-02-20 08:56:41 -08:00
Wladimir J. van der Laan
7b88a61706 Merge pull request #858 from laanwj/2012_02_uisendlabelfix
Only fill in label from address book if no label is filled in yet (fixes #840)
2012-02-20 08:55:49 -08:00
Gregory Maxwell
f50f36d4db Merge pull request #876 from luke-jr/signmsg_desc
Sign message description changes discussed in #bitcoin-dev
2012-02-19 21:24:20 -08:00
Luke Dashjr
5a5cc6ac09 Sign message description changes discussed in #bitcoin-dev 2012-02-19 22:36:59 -05:00
Pieter Wuille
9fa042a96c Typo fix 2012-02-20 04:17:00 +01:00
Pieter Wuille
3a4d81724e Merge pull request #864 from sipa/fix_856
Make compressed pubkeys require client >=0.5.99
2012-02-19 18:21:19 -08:00
Pieter Wuille
49355d9993 Merge pull request #868 from sipa/fix_650
Fix #650: CKey::SetSecret BIGNUM leak
2012-02-19 18:04:46 -08:00
Wladimir J. van der Laan
8a949dd6c3 Merge pull request #867 from laanwj/2012_02_hidetrayicononquit
Hide tray icon in destructor, as deleting will let it linger until quit (on ubuntu)
2012-02-19 11:30:32 -08:00
Pieter Wuille
ceaa13eff2 Report number of (dis)connected blocks in reorganization
Also report old and new best, and fork point.
2012-02-19 20:06:04 +01:00
Pieter Wuille
46245b4782 Fix #616: remove base_uint::operator&=(uint64 b) 2012-02-19 19:12:41 +01:00
Pieter Wuille
a3342d096f Fix #626: RecvLine wrong error message
Also moved RecvLine to net.cpp.
2012-02-19 19:06:42 +01:00
Pieter Wuille
a09f101f14 Fix #650: CKey::SetSecret BIGNUM leak 2012-02-19 18:45:56 +01:00
Pieter Wuille
e0b8d459b1 Merge pull request #863 from sipa/bn2mpifix
Workaround for BN_bn2mpi reading/writing out of bounds
2012-02-19 09:22:11 -08:00
Pieter Wuille
59b1b181e9 Merge pull request #865 from sipa/del_pwalletdb
Free pwalletdbEncryption after encryping wallet
2012-02-19 09:05:40 -08:00
Wladimir J. van der Laan
27a0ed8a0a Hide tray icon in destructor, as deleting will let it linger until quit (on Ubuntu) 2012-02-19 12:07:07 +01:00
Pieter Wuille
fcfd7ff8f8 Free pwalletdbEncryption after encryping wallet
Fixes a memory leak.
2012-02-18 15:44:34 +01:00
Pieter Wuille
38067c18f8 Make compressed pubkeys require 0.6.0 2012-02-18 15:42:38 +01:00
Pieter Wuille
9976cf070f Move GenerateNewKey back to CWallet 2012-02-18 15:42:38 +01:00
Pieter Wuille
0b807a417f Add SetMinVersion to CWallet 2012-02-18 15:42:29 +01:00
Pieter Wuille
e9a041c536 Merge pull request #862 from TheBlueMatt/warnings
Fix compilation warning.
2012-02-18 04:56:58 -08:00
Pieter Wuille
a06113b0c5 Workaround for BN_bn2mpi reading/writing out of bounds
When OpenSSL's BN_bn2mpi is passed a buffer of size 4, valgrind
reports reading/writing one byte past it. I am unable to find
evidence of this behaviour in BN_bn2mpi's source code, so it may
be a spurious warning. However, this change is harmless, as only
the bignum with value 0 results in an mpi serialization of size 4.
2012-02-18 13:32:25 +01:00
Wladimir J. van der Laan
2d36b60f92 Merge pull request #859 from laanwj/2012_02_guilanguagearg
Make it possible to set UI language from commandline (implements #678)
2012-02-18 01:33:56 -08:00
Matt Corallo
db1a5609a0 Fix compilation warning. 2012-02-18 01:22:22 -05:00
Wladimir J. van der Laan
17690ea5a7 Do show/showNormal only when needed. 2012-02-17 23:19:52 +01:00
Wladimir J. van der Laan
328512876a Merge pull request #854 from laanwj/2012_02_qtipc
Restructure IPC URL handling (fixes #851)
2012-02-17 12:54:07 -08:00
Gavin Andresen
d3a4b85670 Merge branch 'nolisten_bitcoin_conf_2' of https://github.com/dooglus/bitcoin 2012-02-17 13:50:40 -05:00
Gavin Andresen
0a6b081cca Merge branch 'testnetmining' of github.com:gavinandresen/bitcoin-git 2012-02-17 13:48:01 -05:00
Gavin Andresen
25bc37f8a2 Merge branch 'threadid' of https://github.com/sipa/bitcoin 2012-02-17 13:40:42 -05:00
Wladimir J. van der Laan
ec2ed58232 Merge pull request #834 from sje397/BackupWallet
Added 'Backup Wallet' menu option to GUI
2012-02-17 10:30:15 -08:00
Wladimir J. van der Laan
72075edafb Allow setting UI language from commandline (implements #678) 2012-02-17 18:47:31 +01:00
Wladimir J. van der Laan
f9f75f320e Only fill in label from address book, if no label is filled in yet, fixes #840 2012-02-17 18:25:14 +01:00
Wladimir J. van der Laan
a3f3e54eee Change #ifdef GUI to #ifdef QT_GUI, GUI is not defined anymore... 2012-02-17 18:01:01 +01:00
Wladimir J. van der Laan
bc5e6b9f21 On windows, show message box with help, as there is no stderr (fixes #702) 2012-02-17 17:55:46 +01:00
Wladimir J. van der Laan
83d1d1a906 Hide window from taskbar when "minimize to tray" active by making window into Tool window 2012-02-17 17:14:02 +01:00
Wladimir J. van der Laan
23b3cf9d10 Restructure IPC URL handling (fixes #851) 2012-02-17 15:32:51 +01:00
Wladimir J. van der Laan
39231e9105 don't allow -daemon in bitcoin-qt (changes only #defines) 2012-02-17 14:47:56 +01:00
Wladimir J. van der Laan
d3896211d2 fix typo in CNetAddr::IsRFC4843() (fixes #850) 2012-02-17 14:40:21 +01:00
Chris Moore
d64e124cf4 Fix #846. Allow negative options such as "nolisten=1" in bitcoin.conf as well as on the command line. 2012-02-16 12:08:58 -08:00
Gavin Andresen
0f8cb5db73 Fix issue #848 : broken mining on testnet 2012-02-16 11:37:54 -05:00
Pieter Wuille
b7c25e0c13 Merge pull request #843 from TheBlueMatt/qrcodedoc
Fix one compile-time warning and fix libqrcode linking in releases
2012-02-16 03:50:59 -08:00
Pieter Wuille
c59881eaee Symbolic names for threads
Introduce an enum threadId, and use symbolic indices when accessing
vnThreadsRunning.
2012-02-16 12:43:06 +01:00
Pieter Wuille
999b4cacaf Merge pull request #844 from sipa/shutdownfix
Several shutdown-related fixes
2012-02-16 03:34:11 -08:00
Pieter Wuille
2030fc6bc2 Merge pull request #842 from sipa/checkaf
Do not create CAddress for invalid accepts
2012-02-16 03:31:14 -08:00
Pieter Wuille
711d5038f5 Merge pull request #828 from sipa/fixwalletlock
Fix wallet locking locking
2012-02-16 03:30:26 -08:00
Matt Corallo
7dcd200489 Properly include $*_LIB_PATH in makefile.unix 2012-02-15 16:39:02 -05:00
Matt Corallo
b03cb15789 Make bitcoin-qt static-link libqrcode and add it for debian pkgs. 2012-02-15 16:39:01 -05:00
Matt Corallo
32af6b16f1 Fix compilation warning. 2012-02-15 16:38:57 -05:00
Pieter Wuille
cc201e01f8 Several shutdown-related fixes
* do not let vnThreadsRunning[1] go negative
* do not perform locking operations while vnThreadsRunning[1] is decreased
* check vnThreadsRunning[1] at exit
2012-02-15 21:17:15 +01:00
Pieter Wuille
25ab17585e Bugfix: do not create CAddress for invalid accepts 2012-02-15 20:56:29 +01:00
Wladimir J. van der Laan
303a47c095 fix default suffixes in save dialog in GNOME, make it more clear that PNG is used (solves #833) 2012-02-15 17:22:00 +01:00
Wladimir J. van der Laan
c85c37acb1 increase BitcoinAddressValidator::MaxAddressLength from 34 to 35
needed for sending BIP16 transactions on test network through GUI
2012-02-15 17:09:47 +01:00
sje397
4efbda3f25 Added 'Backup Wallet' menu option
- icon from the LGPL Nuvola set (like the tick) - http://www.icon-king.com/projects/nuvola/
- include 'boost/version.hpp' in db.cpp so that the overwrite version of copy can be used
- catch exceptions in BackupWallet (e.g. filesystem_error thrown when trying to overwrite without the overwrite flag set)
- include db.h in walletmodel.cpp for BackupWallet function
- updated doc/assets-attribution.txt and contrib/debian/copyright with copyright info for new icon
2012-02-15 23:29:59 +11:00
Wladimir J. van der Laan
1df182ff88 (trivial) regularize coding style 2012-02-15 13:14:16 +01:00
Wladimir J. van der Laan
15b87b2ec4 Merge pull request #807 from TheBlueMatt/bip21
Add req- prefixes to comply with BIP21.
2012-02-12 05:52:34 -08:00
Wladimir J. van der Laan
d27b4576f3 Add export action to file menu (as long as we have a file menu, export certainly should be there) 2012-02-12 12:54:33 +01:00
Wladimir J. van der Laan
2aa3429899 Merge pull request #826 from laanwj/2012_02_fixminimizetotray
Fix Minimize to the tray instead of the taskbar (rework)
2012-02-12 01:49:18 -08:00
gmaxwell
9f3de58d83 Merge pull request #817 from TheBlueMatt/dpiversionfix
Get ext. IP from UPnP, make sure addrMe IsRoutable() in version.
2012-02-11 15:14:02 -08:00
Pieter Wuille
7c39b56c3b Merge pull request #827 from sipa/fixencrypt
Fix wallet encryption with compressed pubkeys
2012-02-11 15:02:05 -08:00
Pieter Wuille
aa625ed6ed Extra wallet locking fixes
* Fix sign error in calculation of seconds to sleep
* Do not mix GetTime() (seconds) and Sleep() (milliseconds)
* Do not sleep forever if walletlock() is called
* Do locking within critical section
2012-02-11 21:59:39 +01:00
Pieter Wuille
b0529ffd95 Fix wallet locking locking 2012-02-11 21:59:39 +01:00
Pieter Wuille
88bc5f9485 Macros for manual critical sections 2012-02-11 21:59:33 +01:00
Janne Pulkkinen
6af93ee2ea Fix Minimize to the tray instead of the taskbar 2012-02-11 18:24:49 +01:00
Gavin Andresen
b25474d1be Merge pull request #825 from sipa/fix_822
Fix #822: use free instead of delete
2012-02-11 09:12:00 -08:00
Pieter Wuille
cd5ee3bbb4 Fix wallet encryption with compressed pubkeys 2012-02-11 16:42:44 +01:00
Pieter Wuille
402deef944 Fix #822 2012-02-11 15:25:42 +01:00
Matt Corallo
245484679a Add Bitcoin-Qt test suite with some bitcoin: URL Tests to start. 2012-02-10 17:47:00 -05:00
Matt Corallo
cce89ead18 Add -req prefixes to comply with BIP21. 2012-02-10 17:44:52 -05:00
Wladimir J. van der Laan
26d9e2c19d Merge pull request #818 from laanwj/2012_02_win32_qtaccessible
Enable accessible widgets Qt module on win32
2012-02-10 09:31:21 -08:00
Gavin Andresen
b0cfef3214 Merge pull request #813 from dooglus/master
Fix #794. Only remove transactions from memory pool when they're actually in the memory pool.
2012-02-10 09:04:19 -08:00
Wladimir J. van der Laan
2e5a781c64 Enable accessible widgets Qt module on win32, so that people with screen readers such as NVDA can make sense of it. 2012-02-10 08:28:32 +01:00
Matt Corallo
baba6e7de2 Get ext. IP from UPnP, make sure addrMe IsRoutable() in version.
This fixes a potential bug where some NATs may replace the node's
interal IP with its external IP in version messages, causing
incorrect checksums when version messages begin being checksummed
on February 14, 2012.
2012-02-10 00:54:11 -05:00
Chris Moore
74f28bf1fd Fix #794. Only remove transactions from memory pool when they're actually in the memory pool. 2012-02-09 05:21:41 -08:00
Wladimir J. van der Laan
328b26d40b Update readme-qt.rst for 0.6.0
- Remove features list (no longer makes sense)
- Document USE_QRCODE
2012-02-07 21:16:28 +01:00
Gavin Andresen
a15bc17632 Merge pull request #805 from luke-jr/gitian_deps
Split dependencies into deps-gitian.yml
2012-02-07 09:23:34 -08:00
Luke Dashjr
f1142dcc5b Update doc/release-process.txt 2012-02-07 12:12:10 -05:00
Luke Dashjr
9909340f37 Split smaller dependencies out of gitian-win32 into deps-win32 2012-02-07 11:52:40 -05:00
Gavin Andresen
882164196e Update all copyrights to 2012 2012-02-07 11:28:30 -05:00
Gavin Andresen
6bf4253a68 Increase client version to 0.6 2012-02-07 11:22:09 -05:00
Gavin Andresen
9d952d17bb Look for flushwallet/listen/irc/dnsseed/upnp instead of noflushwallet/etc. And switch default for irc to 0. 2012-02-07 09:14:31 -05:00
Gavin Andresen
3ad9f8a70f New GetArg features: allow --, and booleans can be -foo or -nofoo 2012-02-07 09:14:31 -05:00
Gavin Andresen
3ae0735553 Unit tests for the GetArg() methods 2012-02-07 09:14:31 -05:00
Gavin Andresen
0b452dff5e Merge branch 'standardScriptSigs' of github.com:gavinandresen/bitcoin-git 2012-02-07 09:04:56 -05:00
Gavin Andresen
7bf8b7c25c -bip16 option (default: 1) to support / not support BIP 16. And bumped default BIP16 switchover date from Feb 15 to Mar 1 2012-02-06 16:27:05 -05:00
Gavin Andresen
0b9a05a2bc Merge branch 'rpcpassword' of https://github.com/gmaxwell/bitcoin 2012-02-06 15:10:30 -05:00
Gavin Andresen
30999ec6f9 Merge branch 'decomposetransfix' of https://github.com/laanwj/bitcoin 2012-02-06 14:50:59 -05:00
Wladimir J. van der Laan
ab07866c8d Restructure credit transaction decomposition (solves issue #689)
When a transaction has multiple outputs that go to the wallet, list these
as multiple transactions in the UI. This is also applied to generated
(coinbase) transactions. Also makes the code shorter and easier
to understand.
2012-02-06 18:13:01 +01:00
Luke Dashjr
f051ee5f96 Update zlib and libpng (previous version had a security issue) 2012-02-06 11:46:49 -05:00
Gavin Andresen
aad945f9b1 Merge branch 'translation-fixes' of https://github.com/tcatm/bitcoin 2012-02-06 09:35:20 -05:00
Gavin Andresen
0104e36d4b Mac deploy tool: make dylibs writeable when copying into app bundle, so they can be stripped/nametool'ed 2012-02-06 09:33:13 -05:00
p2k
f118b5fc5d miniupnpc Porfile removed; new and improved macdeployqtplus
* My patch for miniupnpc has made it into the latest MacPorts release: https://trac.macports.org/ticket/31354
* Documentation has been changed appropriately
* New pure-Python macdeployqt; leverages all problems with the stock macdeployqt
2012-02-06 09:33:12 -05:00
Nils Schneider
9d4b05c0dc fetch translations from transifex
* fixes issue #742
* new translations: cs_CZ fa fi fr_FR hr pl ro_RO sv tr
2012-02-05 16:40:27 +01:00
Wladimir J. van der Laan
f69b82e78a Change up/down increment in UI to 0.001 BTC (issue #760) 2012-02-05 12:15:16 +01:00
Gregory Maxwell
b04f301c8e Have bitcoind recommend a secure RPC password. Increase invalid password delay.
Help users avoid insecure configurations a bit by recommending a
secure RPC password and increasing the incorrect password delay.

This may open up a RPC DOS for users with exposed RPC ports and
short passwords. Since users shouldn't have exposed RPC ports OR
short passwords, the DOS risk is preferable to the compromise
risk.

Also logs the client IP address for incorrect attempts.
2012-02-05 02:58:35 -05:00
Gregory Maxwell
5d1b8f1725 Avoid advertising the node's address when it is not listening or IsInitialBlockDownload().
This also avoids flushing setAddrKnown until 24 hours has passed,
and avoids contacting the external IP services when not listening.

Advertising non-listening nodes is just addr message spam.
It doesn't help the network, in fact it hurts the network,
and it also hurts user's privacy.

Advertising far out of sync nodes doesn't help the network—
they can't even forward (most) transactions and wastes nodes
outbound slots.
2012-02-01 18:08:03 -05:00
Wladimir J. van der Laan
d2291cce92 Remove loose amp; from Portugese translation (issue #701) 2012-02-01 20:14:13 +01:00
Gavin Andresen
8beb917c6c Allow -upnp to override setting in wallet (and simplify logic a bit) 2012-02-01 13:24:15 -05:00
Matt Corallo
177dbcaace Fix UPnP by reannouncing every 20 minutes. 2012-01-31 17:42:15 -05:00
Gavin Andresen
c52296a73e Testnet difficulty calculation changes, to take effect Feb 15 2012
Allow mining of min-difficulty blocks if 20 minutes have gone by without mining a regular-difficulty block.
Normal rules apply every 2016 blocks, though, so there may be a very-slow-to-confirm block at the difficulty-adjustment blocks.
2012-01-31 13:20:01 -05:00
Gavin Andresen
4477b17f15 Merge branch 'checkkeys' of https://github.com/sipa/bitcoin 2012-01-31 12:19:26 -05:00
Gavin Andresen
68649bef93 CreateNewBlock was not adding in transaction fees. 2012-01-28 10:16:21 -05:00
Luke Dashjr
2bc4fd609c Bitcoin-Qt signmessage GUI (pull request #582) 2012-01-27 08:41:55 +01:00
Pieter Wuille
91f43a33f8 Full checking of all loaded keys 2012-01-26 19:26:43 +01:00
Wladimir J. van der Laan
70f55355e2 Merge pull request #593 (Full URL Support in bitcoin-qt) 2012-01-26 19:00:02 +01:00
Gavin Andresen
4c932cca6f Merge pull request #782 from sipa/checkkeys
Check consistency of private keys
2012-01-25 05:43:44 -08:00
Gavin Andresen
b6a35d2d52 Merge pull request #773 from gavinandresen/p2shSigOpCount
Simplify counting of P2SH sigops to match BIP 16
2012-01-25 05:21:20 -08:00
Pieter Wuille
b25cc627a3 Check consistency of private keys
Reported by onlineproof on IRC: Bitcoin does not verify whether private
keys and public keys correspond, when loading a wallet.
2012-01-25 03:05:16 +01:00
Gavin Andresen
341519523f Support makefile.osx building test_bitcoin with dynamic boost 2012-01-23 15:58:06 -05:00
Gavin Andresen
2a9b46cf4b Merge branch 'bugfix_shared_boost_test' of https://github.com/luke-jr/bitcoin 2012-01-23 15:16:59 -05:00
Luke Dashjr
34c69036da Rename src/obj/test to src/obj-test to workaround bug in older GNU Make 2012-01-23 14:27:08 -05:00
Gavin Andresen
a702ceaafc Merge branch 'lockcontention' of https://github.com/TheBlueMatt/bitcoin 2012-01-23 13:15:43 -05:00
Gavin Andresen
9ef59797af Merge branch 'master' of github.com:bitcoin/bitcoin 2012-01-23 13:14:49 -05:00
Gavin Andresen
b8056dc5d0 Merge branch 'bugfix_areinpstd' of https://github.com/luke-jr/bitcoin 2012-01-23 13:09:34 -05:00
Gavin Andresen
5e437f05c7 Merge pull request #764 from luke-jr/update_release_process
Various updates to the release process
2012-01-23 09:59:38 -08:00
Gavin Andresen
149f580c82 Only store transactions with missing inputs in the orphan pool.
All previous versions of bitcoin could store some types of
invalid transactions in the orphan-transaction list.
2012-01-23 12:54:32 -05:00
Gavin Andresen
dc77dce07c Fixed addmultisigaddress if looking up public keys from locked wallets. 2012-01-23 12:04:34 -05:00
Luke Dashjr
ca9afa8401 Bugfix: Support building test_bitcoin with shared-object boost test framework 2012-01-23 11:37:48 -05:00
Matt Corallo
198fb229a4 Add DEBUG_LOCKCONTENTION, to warn each time a thread waits to lock.
If compiled with -DDEBUG_LOCKCONTENTION, Bitcoin will print to
debug.log each time a thread has to wait for a lock to continue.
2012-01-21 16:16:28 -05:00
Luke Dashjr
575bdcde93 Sanitize AreInputsStandard slightly
Correct comment for why the check is unnecessary for coinbases
Move testnet check out, to AcceptToMemoryPool where everything else checks it
2012-01-20 21:00:08 -05:00
Gavin Andresen
137d0685a4 Simplify counting of P2SH sigops to match BIP 16 (thanks to Matt Corallo for prompting this).
This also removes an un-needed sigops-per-byte check when accepting transactions to the memory pool (un-needed assuming only standard transactions are being accepted). And it only counts P2SH sigops after the switchover date.
2012-01-20 17:07:40 -05:00
Gavin Andresen
1240a1b0a8 Back out spacing changes to json spirit code 2012-01-19 14:32:45 -05:00
Gavin Andresen
7012b124bc Merge branch 'updateseednodes' of https://github.com/nanotube/bitcoin 2012-01-19 14:23:49 -05:00
Gavin Andresen
c55fd06b99 Merge branch 'tabs-to-space' of https://github.com/larsr/bitcoin 2012-01-19 14:22:26 -05:00
Gavin Andresen
aacefd2795 Merge branch 'getmemorypool_blockflagstime' of https://github.com/forrestv/bitcoin 2012-01-19 14:14:41 -05:00
Gavin Andresen
39f0d96860 Make transactions with extra data in their scriptSig's non-standard. 2012-01-19 13:30:54 -05:00
Daniel Folkinshteyn
b2f76e9ded Update seednodes, pick long-uptime nodes with version >= 0.4.0 2012-01-19 01:54:14 -05:00
Luke Dashjr
9965e1d044 Various updates to the release process 2012-01-17 21:50:08 -05:00
Wladimir J. van der Laan
43cda5f325 Merge pull request #762 from laanwj/qtprogressfix
Revert to global progress indication, also fix the build
2012-01-17 00:35:16 -08:00
Wladimir J. van der Laan
06706ab8ef Remove erroneous ":" in front of port in options dialog (introduced with network refactor) 2012-01-17 09:34:24 +01:00
Wladimir J. van der Laan
be4d08b261 fix the build (port IP validation in options to network refactoring) 2012-01-17 09:27:03 +01:00
Wladimir J. van der Laan
b2a967cd0b Revert to global progress indication (see #753) 2012-01-17 09:19:58 +01:00
Pieter Wuille
c981d768b3 Fix handling of default ports 2012-01-17 02:12:35 +01:00
Gavin Andresen
8498c59144 Merge branch 'keepnode' of https://github.com/TheBlueMatt/bitcoin 2012-01-16 16:45:43 -05:00
Wladimir J. van der Laan
5dc090009e Merge pull request #758 from Matoking/master
Ui: Clear All tooltip and updated About dialog with 2012
2012-01-15 08:09:53 -08:00
Forrest Voight
ab84512258 Added mintime and curtime to RPC getmemorypool 2012-01-14 19:23:37 -05:00
Forrest Voight
52a3d2635c Separated COINBASE_FLAGS out into main.h and made RPC getmemorypool return it 2012-01-14 19:22:24 -05:00
Janne Pulkkinen
29b7273153 *Clear all has a tooltip now *About dialog updated 2012-01-14 21:31:49 +02:00
Lars Rasmusson
b985efaac1 Replace tabs with four spaces to comply with coding standard in doc/coding.txt 2012-01-14 12:14:36 +01:00
Gavin Andresen
9e8818ec9d Remove base58 encoding from validateaddress/addmultisigaddress
base58-encoding of full/compressed public keys needs more thought; it probably makes sense to define a base58 encoding that includes a version byte and a checksum. So just support hex and bitcoin-address encodings for now.
2012-01-13 10:22:24 -05:00
Gavin Andresen
4063460534 Refactor: needing to call ConnectInputs to process coinbase transactions was counter-intuitive 2012-01-13 10:22:24 -05:00
Gavin Andresen
8d7849b6db Refactored ConnectInputs, so valid-transaction-checks are done before ECDSA-verifying signatures. 2012-01-13 10:22:24 -05:00
Gavin Andresen
922e8e2929 Replace OP_EVAL (BIP 12) with Pay-to-script-hash (BIP 16). 2012-01-13 10:22:23 -05:00
Gavin Andresen
d11a58a2d3 Remove not-used-anywhere scriptPrereq from SignSignature() 2012-01-13 10:20:42 -05:00
Gavin Andresen
f290a649f9 Merge branch 'getmininginfo' of https://github.com/luke-jr/bitcoin 2012-01-13 10:06:05 -05:00
Matt Corallo
10ba0a3efc Minor code cleanup to use fHaveUPnP instead of #ifdef 2012-01-12 22:13:16 -05:00
Matt Corallo
b24e6e4d1b Add -keepnode which attempts to -addnode and keep a connection open 2012-01-12 22:13:16 -05:00
Gavin Andresen
a1de57a063 Compile with extra warnings turned on. And more makefile/code tidying up.
This turns on most gcc warnings, and removes some unused variables and other code that triggers warnings.
Exceptions are:
 -Wno-sign-compare : triggered by lots of comparisons of signed integer to foo.size(), which is unsigned.
 -Wno-char-subscripts : triggered by the convert-to-hex functions (I may fix this in a future commit).
2012-01-12 20:02:47 -05:00
Luke Dashjr
340f0876ea collect more info on tx pooling and block finding for getmininginfo 2012-01-12 19:47:39 -05:00
Luke Dashjr
6950bb6200 Add new "getmininginfo" JSON-RPC method, with mining-only fields moved out of "getinfo" 2012-01-12 19:47:23 -05:00
Gavin Andresen
025d495481 Remove broken Visual C++ makefile.vc, and removed annoying HEADERS= list from other makefiles 2012-01-12 16:55:44 -05:00
Gavin Andresen
3f64fa1369 Merge pull request #743 from gavinandresen/blocknotify
-blocknotify : run a command when best-block changes
2012-01-12 06:31:25 -08:00
Pieter Wuille
afcf6f974f Merge pull request #649 from sipa/comprpubkey
Compressed pubkeys
2012-01-10 13:23:51 -08:00
Wladimir J. van der Laan
b43eaa5508 Merge pull request #752 from luke-jr/qt_txnid
Qt: Show transaction ID in details
2012-01-10 11:51:55 -08:00
Luke Dashjr
ebf9065c22 Qt: Show transaction ID in details 2012-01-10 13:25:05 -05:00
Pieter Wuille
a4902c9e7c Remove unused definition 2012-01-09 23:39:26 +01:00
Gavin Andresen
2e555237d3 Merge pull request #746 from laanwj/tdesc_ro
make transaction description read-only (UI fix)
2012-01-09 07:59:18 -08:00
Gavin Andresen
7501d61633 Merge pull request #750 from TheBlueMatt/anonymous
Remove mentions on anonymity in debian folder.
2012-01-09 07:58:58 -08:00
Pieter Wuille
b3974ec9d4 Unit tests for EC key routines
This tests:
* creation of keys from base58-encoded strings
* extracting public keys and addresses
* compressed public keys
* compact signatures and key recovery
2012-01-09 15:18:19 +01:00
Pieter Wuille
d4d9c734c3 Compact signatures with compressed pubkeys 2012-01-09 15:18:19 +01:00
Pieter Wuille
11529c6e4f Compressed pubkeys
This patch enabled compressed pubkeys when -compressedpubkeys is passed.
These are 33 bytes instead of 65, and require only marginally more CPU
power when verifying. Compressed pubkeys have a different corresponding
address, so it is determined at generation. When -compressedpubkeys is
given, all newly generated addresses will use a compressed key, while
older/other addresses keep using normal keys. Unpatched clients will
relay and verify these transactions.
2012-01-09 15:18:19 +01:00
Matt Corallo
65c82be021 Remove mentions on anonymity in debian folder.
These should never have been there, bitcoin isnt anonymous without
a ton of work that virtually no users will ever be willing and
capable of doing.
2012-01-07 13:38:43 -05:00
Pieter Wuille
1684f98b27 Merge pull request #735 from sipa/netbase
Network stack refactor
2012-01-07 06:19:46 -08:00
Pieter Wuille
67a42f929b Network stack refactor
This introduces CNetAddr and CService, respectively wrapping an
(IPv6) IP address and an IP+port combination. This functionality used
to be part of CAddress, which also contains network flags and
connection attempt information. These extra fields are however not
always necessary.

These classes, along with logic for creating connections and doing
name lookups, are moved to netbase.{h,cpp}, which does not depend on
headers.h.

Furthermore, CNetAddr is mostly IPv6-ready, though IPv6
functionality is not yet enabled for the application itself.
2012-01-06 18:55:37 +01:00
Wladimir J. van der Laan
7453497ee4 make transaction description read-only (UI fix) 2012-01-06 06:57:14 +01:00
Gavin Andresen
7486c64dd8 Merge pull request #740 from TheBlueMatt/perf
Fix horrific performance found by gmaxwell.
2012-01-05 05:37:23 -08:00
Matt Corallo
7d145a0f59 Add support for opening bitcoin: URIs directly. 2012-01-05 00:29:28 -05:00
Matt Corallo
9a93c4c024 Automatically refocus on new SendCoinsEntrys and scroll to them. 2012-01-05 00:29:28 -05:00
Matt Corallo
f7a9a11391 Fix horrific performance found by gmaxwell. 2012-01-04 19:46:16 -05:00
Gavin Andresen
d237f62c23 -blocknotify=command argument, implemented using system() and boost::thread 2012-01-03 15:48:59 -05:00
Gavin Andresen
96d3bcb996 Merge pull request #731 from laanwj/txshowfix
Fix transaction type in UI
2012-01-03 09:24:54 -08:00
Gavin Andresen
af8c56f8be Merge branch 'getblock' 2012-01-03 12:16:56 -05:00
Gavin Andresen
8677f9c751 I broke -testnet with my TOR option-parsing fixes. 2012-01-03 11:17:24 -05:00
Gavin Andresen
112b0e97d4 Merge pull request #741 from laanwj/typo734fix
Fix typo (#734)
2012-01-03 07:54:38 -08:00
Gavin Andresen
73e86eedd5 Merge branch 'bugfix_multisig' of https://github.com/coderrr/bitcoin 2012-01-03 10:23:20 -05:00
Gavin Andresen
daad9a9a71 Merge branch 'gitianfix' of https://github.com/TheBlueMatt/bitcoin 2012-01-03 10:22:24 -05:00
Gavin Andresen
0fcf91ea1e Fix issue #659, and cleanup wallet/command-line argument handling a bit 2012-01-03 10:17:28 -05:00
Wladimir J. van der Laan
ecaa91d1df Fix typo (#734) 2012-01-03 11:57:24 +01:00
Pieter Wuille
4231eb217c Merge pull request #738 from sipa/dnsseed-fix
Fix dnsseed deadlock
2012-01-02 17:04:09 -08:00
Pieter Wuille
a75d7066b8 Fix some address-handling deadlocks
Made three critical blocks for cs_mapAddresses smaller, and moved
writing to the database out of them. This should also improve the
concurrency of the code.
2012-01-03 02:01:56 +01:00
coderrr
6ec76ca09e make sure IsMine only returns true when we own all keys 2012-01-03 06:24:52 +07:00
Wladimir J. van der Laan
56c6e3696d Fix transaction type in UI: not all tx'es with "from"/"to" field are necessarily IP tx'es
- Also, prepare for OP_EVAL by calling all transactions without bitcoin address "SendToOther"/"RecvFromOther",
 (IP tx'es are so rare they can be put together with funky EV_EVAL scripts)
2011-12-28 11:14:05 +01:00
Gavin Andresen
625b56de64 Merge branch 'opevalcountfix' of https://github.com/laanwj/bitcoin 2011-12-27 16:42:29 -05:00
Gavin Andresen
6d6d392b22 Fixed OP_EVAL recursion unit test, checks for both infinite and exactly-3-deep recursion 2011-12-27 16:41:56 -05:00
Wladimir J. van der Laan
89772f932a Fix OP_EVAL recursion depth counting 2011-12-27 10:02:28 +01:00
Gavin Andresen
61977f956c Check all prevout.n if one transaction provides multiple inputs 2011-12-25 10:32:05 -05:00
Gavin Andresen
60835d9627 assert condition in previous commit was backwards 2011-12-25 10:08:01 -05:00
Gavin Andresen
6996a9d713 Check for valid prevout.n in FetchInputs.
IsStandardInputs could crash if given invalid input index.
2011-12-25 08:45:09 -05:00
Matt Corallo
0b5d6f1e26 Add QR Code support to Win32 Gitian build. 2011-12-25 02:15:16 -08:00
Matt Corallo
1194739745 Fix Linux gitian descriptor to use QRCode support. 2011-12-23 15:35:59 -08:00
Matt Corallo
cad5745138 Add libqrencode-dev to the debian/ubuntu apt-get lines. 2011-12-23 15:34:48 -08:00
Matt Corallo
56690a69d6 No reason to have any qrcode stuff in the bitcoind osx makefile. 2011-12-23 15:28:35 -08:00
Gavin Andresen
fe358165e3 Be more conservative: check all transactions in blocks after last checkpoint. 2011-12-23 17:13:10 -05:00
Gavin Andresen
8a53cb0b9d New RPC commands: getblockhash and getblock 2011-12-23 16:26:38 -05:00
Wladimir J. van der Laan
5ad2ca011e Merge pull request #723 from TheBlueMatt/gitianfix
Fix #722.
2011-12-23 03:53:31 -08:00
Wladimir J. van der Laan
3a6ede13f8 Merge pull request #683 from laanwj/ui_copy_amount
Context menu updates for TransactionView and AddressTablePage
2011-12-23 03:21:01 -08:00
Wladimir J. van der Laan
c58e7d4e01 Copy amount to clipboard (implements #657)
- Also, unify similar code related to copying transaction fields to clipboard
2011-12-23 12:07:23 +01:00
Wladimir J. van der Laan
c4a4a4b886 Add context menu for address book page (implements part 1 of issue #648) 2011-12-23 12:07:23 +01:00
Wladimir J. van der Laan
e073457191 Move HtmlEscape (escape for qt rich text controls) to qt gui utilities 2011-12-23 12:07:23 +01:00
Wladimir J. van der Laan
c75abc9f7e Comments update 2011-12-23 12:07:23 +01:00
Wladimir J. van der Laan
96b1e085c3 Merge pull request #629 from sje397/master
QR Code generation via libqrencode
2011-12-23 02:50:28 -08:00
Matt Corallo
7415b805c4 Fix #722. 2011-12-23 02:24:46 -08:00
Gavin Andresen
2e17ac83c6 Fix broken ExtractAddress (refactored, made callers check for addresses in keystore if they care) 2011-12-22 15:57:31 -05:00
Gavin Andresen
ce336fdc21 Back out testnet default address change, it breaks accounts on old wallets. 2011-12-22 15:56:45 -05:00
Wladimir J. van der Laan
bde280b9a4 Revert "Use standard C99 (and Qt) types for 64-bit integers"
This reverts commit 21d9f36781.
2011-12-21 22:33:19 +01:00
Luke Dashjr
21d9f36781 Use standard C99 (and Qt) types for 64-bit integers 2011-12-20 16:52:59 -05:00
Gavin Andresen
781c06c0f5 Merge pull request #677 from luke-jr/minfee_modes
API: GetMinFee modes
2011-12-20 13:09:18 -08:00
Gavin Andresen
595925592d Merge branch 'op_eval' 2011-12-20 14:43:31 -05:00
Gavin Andresen
f06e3e0ea6 Merge pull request #717 from TheBlueMatt/installerqtupgrade
Implement "Start on window system startup" on Win32 + Linux.
2011-12-20 11:42:53 -08:00
Matt Corallo
f18a119ac0 Implement "Start on window system startup" on Win32 + Linux. 2011-12-20 13:51:06 -05:00
Gavin Andresen
77f21f1583 include util.h to get SecureString definition. 2011-12-20 12:21:47 -05:00
Gavin Andresen
0e87f34bed Include limits, not climints (using std::numeric_limits now) 2011-12-20 12:04:33 -05:00
Gavin Andresen
387c8e3c5b Merge pull request #673 from mndrix/less-time-data
Store fewer time samples
2011-12-20 08:55:55 -08:00
Gavin Andresen
74f5435e10 Merge pull request #716 from gavinandresen/cleanup
Cleanups suggested by genjix
2011-12-20 08:52:22 -08:00
sje397
22123c85f3 Added QRCode generation functions via libqrencode. Switch on with USE_QRENCODE=1.
Amended build docs for Linux and OSX, and OSX makefile.
Added package 'qrencode' to gitian.yml
2011-12-20 22:11:24 +11:00
Gavin Andresen
9ef7fa3447 Code cleanup: use ECDSA_size() instead of fixed 10,000 byte sig buffer, and explicity init static var 2011-12-19 19:10:34 -05:00
Gavin Andresen
26ce92b352 Use std::numeric_limits<> for typesafe INT_MAX/etc 2011-12-19 19:10:34 -05:00
Gavin Andresen
bd846c0e56 Cleanup: removed dead code, and use C99 typedefs for int64 (supported by all modern c++ compilers) 2011-12-19 19:10:34 -05:00
Gavin Andresen
3528650560 Merge pull request #690 from runeksvendsen/qt-cmdline-options-parsing
When using Qt GUI, move parameter-parsing to start of qt/bitcoin.cpp:main()
2011-12-19 12:23:00 -08:00
Gavin Andresen
bafb43d6c1 Merge branch 'txn_block_info' of https://github.com/luke-jr/bitcoin 2011-12-19 15:14:22 -05:00
Gavin Andresen
9e470585b3 Update bitcoin address numbers for latest luke-jr/sipa scheme 2011-12-19 13:24:51 -05:00
Gavin Andresen
be237c119e Fix logic for IsChange() for send-to-self transactions. 2011-12-19 13:24:49 -05:00
Gavin Andresen
2a45a494b0 Use block times for 'hard' OP_EVAL switchover, and refactored EvalScript
so it takes a flag for how to interpret OP_EVAL.
Also increased IsStandard size of scriptSigs to 500 bytes, so
a 3-of-3 multisig transaction IsStandard.
2011-12-19 13:24:48 -05:00
Gavin Andresen
a0871afb2b Interpret OP_EVAL as OP_NOP until Feb 1, 2012 2011-12-19 13:24:48 -05:00
Gavin Andresen
fae3e2aab6 Disable addmultisigaddress if not testnet 2011-12-19 13:24:48 -05:00
Gavin Andresen
d7062ef1bd Put OP_EVAL string in coinbase of generated blocks 2011-12-19 13:24:48 -05:00
Pieter Wuille
3ae65166b5 add key.o and rpcdump.o to makefile.linux-mingw 2011-12-19 19:20:53 +01:00
Gavin Andresen
e679ec969c OP_EVAL implementation
OP_EVAL is a new opcode that evaluates an item on the stack as a script.
It enables a new type of bitcoin address that needs an arbitrarily
complex script to redeem.
2011-12-19 12:40:19 -05:00
Gavin Andresen
cc40ba2151 Global fixture to send output to console instead of debug.log 2011-12-19 12:40:19 -05:00
Gavin Andresen
bf798734db Support 3 new multisignature IsStandard transactions
Initial support for (a and b), (a or b), and 2-of-3 escrow
transactions (where a, b, and c are keys).
2011-12-19 12:40:19 -05:00
Gavin Andresen
1466b8b78a Rework unit tests so test_bitcoin.cpp does not #include them all 2011-12-19 12:39:47 -05:00
Gavin Andresen
7e55c1ab65 Collapse no-op ExtractAddress/ExtractAddressInner 2011-12-19 12:39:47 -05:00
Gavin Andresen
99a289f531 Merge pull request #574 from sipa/dumpprivkey
Dumpprivkey
2011-12-19 07:27:25 -08:00
Gavin Andresen
fc90967876 Merge pull request #699 from laanwj/about_qt
Add "About Qt" menu option to show built-in Qt About dialog
2011-12-19 07:26:14 -08:00
Gavin Andresen
1f3bc1c239 Merge pull request #707 from gavinandresen/BIP14
Implement BIP 14 : separate protocol version from client version
2011-12-19 07:25:16 -08:00
Gavin Andresen
f8ded588a2 Implement BIP 14 : separate protocol version from client version 2011-12-19 10:24:23 -05:00
Gavin Andresen
cd2b8832fd Merge pull request #709 from luke-jr/newdnsseeds
New DNS seeds
2011-12-19 07:12:30 -08:00
Pieter Wuille
95d888a6d1 Key import and export
Introduces two new RPC calls:
* dumpprivkey: retrieve the private key corresponding to an address
* importprivkey: add a private key to your wallet

The private key format is analoguous to the address format. It is
a 51-character base58-encoded string, that includes a version number
and a checksum.

Includes patch by mhanne:
* add optional account parameter for importprivkey, if omitted use default
2011-12-17 21:49:48 +01:00
Pieter Wuille
30ab2c9c46 Preparations for key import/export 2011-12-17 21:49:48 +01:00
Pieter Wuille
15a8590ecf CBitcoinSecret added (base58 encoded privkey) 2011-12-17 21:49:48 +01:00
Pieter Wuille
93db3fceac Add GetSecret() and GetKeys() to CKeyStore 2011-12-17 21:49:47 +01:00
Pieter Wuille
4c6e22953e Make CWalletTx::pwallet private 2011-12-17 21:49:47 +01:00
Luke Dashjr
cce16fdc68 Add blockhash and blockindex to transaction info 2011-12-16 19:05:41 -05:00
Luke Dashjr
647734881c Add my DNS seed domain 2011-12-16 18:34:47 -05:00
Gavin Andresen
8214620178 Merge pull request #704 from TheBlueMatt/master
Update debian changelog to 0.5.1.
2011-12-16 14:19:32 -08:00
Gavin Andresen
f0a70570fe Merge pull request #706 from TheBlueMatt/gitian
Add laanwj to gitian download scripts.
2011-12-16 14:15:28 -08:00
Gavin Andresen
6e39e7c9b3 Move more newlines out of strings, and fix translations. 2011-12-16 17:13:45 -05:00
Gavin Andresen
ab6c45372c Merge branch 'fix-help-translations' of https://github.com/tcatm/bitcoin 2011-12-16 16:37:24 -05:00
Matt Corallo
fdaf1dfd2e Add laanwj to gitian download scripts. 2011-12-16 15:06:17 -05:00
Matt Corallo
4051e79887 Update debian changelog to 0.5.1. 2011-12-16 13:27:52 -05:00
Gavin Andresen
8896c2d9d6 Bump version 0.5.99 (prep for pulling for version 0.6) 2011-12-16 12:31:59 -05:00
Matt Corallo
61a8c0569e Add sipa's new dnsseed. 2011-12-16 11:30:36 -05:00
Luke Dashjr
dbbf1d4a48 GetMinFee takes a mode parameter (GMF_{BLOCK,RELAY,SEND}) instead of fForRelay 2011-12-14 01:07:43 -05:00
Luke Dashjr
a880b29cab Bugfix: fForRelay should be false when deciding required fee to include in blocks
During the rushed transition from 0.01 BTC to 0.0005 BTC fees, we took the
approach of dropping the relay and block-inclusion fee to 0.0005 BTC
immediately, and only delayed adjusting the sending fee for the next release.
Afterward, the relay fee was lowered to 0.0001 BTC to avoid having the same
problem in the future. However, the block inclusion code was left setting
fForRelay to true! This fixes that, so the lower 0.0001 BTC allowance is (as
intended) only permitted for real relaying.
2011-12-14 01:06:21 -05:00
Wladimir J. van der Laan
01ea41b203 Add "About Qt" menu option to show built-in Qt About dialog
- Most Qt programs do this, and it can be useful to find out what version of Qt was built against.
2011-12-13 17:35:17 +01:00
Nils Schneider
43421af2e4 move \\n outside _() in --help 2011-12-13 06:46:37 +01:00
Rune K Svendsen
4dba26620c When using Qt GUI, move parameter-parsing to start of qt/bitcoin.cpp:main() 2011-12-09 19:19:27 +01:00
Michael Hendricks
1c4aab926e Retain only the most recent time samples
Remembering all time samples makes nTimeOffset slow to respond to
system clock corrections.  For instance, I start my node with a system
clock that's 30 minutes slow and run it for a few days.  During that
time, I accumulate 10,000 offset samples with a median of 1800
seconds.  Now I correct my system clock.  Without this change, my node
must collect another 10,000 samples before nTimeOffset is correct
again.  With this change, I must only accumulate 100 samples to
correct the offset.

Storing unlimited time samples also allows an attacker with many IP
addresses (ex, a large botnet) to perform a memory exhaustion attack
against Bitcoin nodes.  The attacker sends a version message from each
IP to his target, consuming more of the target's memory each time.
Time samples are small, so this attack might be impractical under the
old code, but it's impossible with the new code.
2011-12-01 17:28:14 -07:00
Michael Hendricks
5e1ddc4210 Only log time samples in debug mode
The full list of time samples is rarely useful outside of debugging.
The node's time offset, however is useful for discovering local clock
drift, so it's displayed in all logging modes.
2011-12-01 17:28:14 -07:00
201 changed files with 57038 additions and 18773 deletions

1
.gitattributes vendored Normal file
View File

@@ -0,0 +1 @@
src/version.cpp export-subst

1
.gitignore vendored
View File

@@ -1,6 +1,7 @@
src/*.exe
src/bitcoin
src/bitcoind
src/build.h
.*.swp
*.*~*
*.bak

View File

@@ -1,4 +1,4 @@
Copyright (c) 2009-2011 Bitcoin Developers
Copyright (c) 2009-2012 Bitcoin Developers
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@@ -1,6 +1,6 @@
TEMPLATE = app
TARGET =
VERSION = 0.5.1
VERSION = 0.6.1
INCLUDEPATH += src src/json src/qt
DEFINES += QT_GUI BOOST_THREAD_USE_LIB
CONFIG += no_include_pwd
@@ -30,6 +30,14 @@ contains(RELEASE, 1) {
}
}
# use: qmake "USE_QRCODE=1"
# libqrencode (http://fukuchi.org/works/qrencode/index.en.html) must be installed for support
contains(USE_QRCODE, 1) {
message(Building with QRCode support)
DEFINES += USE_QRCODE
LIBS += -lqrencode
}
# use: qmake "USE_UPNP=1" ( enabled by default; default)
# or: qmake "USE_UPNP=0" (disabled by default)
# or: qmake "USE_UPNP=-" (not supported)
@@ -54,15 +62,15 @@ contains(USE_DBUS, 1) {
QT += dbus
}
# use: qmake "USE_SSL=1"
contains(USE_SSL, 1) {
message(Building with SSL support for RPC)
DEFINES += USE_SSL
# use: qmake "FIRST_CLASS_MESSAGING=1"
contains(FIRST_CLASS_MESSAGING, 1) {
message(Building with first-class messaging)
DEFINES += FIRST_CLASS_MESSAGING
}
contains(BITCOIN_NEED_QT_PLUGINS, 1) {
DEFINES += BITCOIN_NEED_QT_PLUGINS
QTPLUGIN += qcncodecs qjpcodecs qtwcodecs qkrcodecs
QTPLUGIN += qcncodecs qjpcodecs qtwcodecs qkrcodecs qtaccessiblewidgets
}
!windows {
@@ -72,23 +80,35 @@ contains(BITCOIN_NEED_QT_PLUGINS, 1) {
# do not enable this on windows, as it will result in a non-working executable!
}
# disable quite some warnings because bitcoin core "sins" a lot
QMAKE_CXXFLAGS_WARN_ON = -fdiagnostics-show-option -Wall -Wno-strict-aliasing -Wno-invalid-offsetof -Wno-unused-variable -Wno-unused-parameter -Wno-sign-compare -Wno-char-subscripts -Wno-unused-value -Wno-sequence-point -Wno-parentheses -Wno-unknown-pragmas -Wno-switch
# 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.target = genbuildhook
PRE_TARGETDEPS += genbuildhook
QMAKE_EXTRA_TARGETS += genbuild
DEFINES += HAVE_BUILD_INFO
}
QMAKE_CXXFLAGS_WARN_ON = -fdiagnostics-show-option -Wall -Wextra -Wformat -Wformat-security -Wno-invalid-offsetof -Wno-sign-compare -Wno-unused-parameter
# Input
DEPENDPATH += src/qt src src json/include
DEPENDPATH += src src/json src/qt
HEADERS += src/qt/bitcoingui.h \
src/qt/transactiontablemodel.h \
src/qt/addresstablemodel.h \
src/qt/optionsdialog.h \
src/qt/sendcoinsdialog.h \
src/qt/addressbookpage.h \
src/qt/messagepage.h \
src/qt/aboutdialog.h \
src/qt/editaddressdialog.h \
src/qt/bitcoinaddressvalidator.h \
src/addrman.h \
src/base58.h \
src/bignum.h \
src/checkpoints.h \
src/compat.h \
src/util.h \
src/uint256.h \
src/serialize.h \
@@ -97,11 +117,11 @@ HEADERS += src/qt/bitcoingui.h \
src/net.h \
src/key.h \
src/db.h \
src/walletdb.h \
src/script.h \
src/noui.h \
src/init.h \
src/headers.h \
src/irc.h \
src/mruset.h \
src/json/json_spirit_writer_template.h \
src/json/json_spirit_writer.h \
src/json/json_spirit_value.h \
@@ -117,7 +137,6 @@ HEADERS += src/qt/bitcoingui.h \
src/qt/guiconstants.h \
src/qt/optionsmodel.h \
src/qt/monitoreddatamapper.h \
src/qtui.h \
src/qt/transactiondesc.h \
src/qt/transactiondescdialog.h \
src/qt/bitcoinamountfield.h \
@@ -136,7 +155,10 @@ HEADERS += src/qt/bitcoingui.h \
src/qt/qvaluecombobox.h \
src/qt/askpassphrasedialog.h \
src/protocol.h \
src/qt/notificator.h
src/qt/notificator.h \
src/qt/qtipcserver.h \
src/allocators.h \
src/ui_interface.h
SOURCES += src/qt/bitcoin.cpp src/qt/bitcoingui.cpp \
src/qt/transactiontablemodel.cpp \
@@ -144,17 +166,23 @@ SOURCES += src/qt/bitcoin.cpp src/qt/bitcoingui.cpp \
src/qt/optionsdialog.cpp \
src/qt/sendcoinsdialog.cpp \
src/qt/addressbookpage.cpp \
src/qt/messagepage.cpp \
src/qt/aboutdialog.cpp \
src/qt/editaddressdialog.cpp \
src/qt/bitcoinaddressvalidator.cpp \
src/version.cpp \
src/util.cpp \
src/netbase.cpp \
src/key.cpp \
src/script.cpp \
src/main.cpp \
src/init.cpp \
src/net.cpp \
src/irc.cpp \
src/checkpoints.cpp \
src/addrman.cpp \
src/db.cpp \
src/walletdb.cpp \
src/json/json_spirit_writer.cpp \
src/json/json_spirit_value.cpp \
src/json/json_spirit_reader.cpp \
@@ -173,6 +201,7 @@ SOURCES += src/qt/bitcoin.cpp src/qt/bitcoingui.cpp \
src/qt/transactionview.cpp \
src/qt/walletmodel.cpp \
src/bitcoinrpc.cpp \
src/rpcdump.cpp \
src/qt/overviewpage.cpp \
src/qt/csvmodelwriter.cpp \
src/crypter.cpp \
@@ -182,7 +211,8 @@ SOURCES += src/qt/bitcoin.cpp src/qt/bitcoingui.cpp \
src/qt/qvaluecombobox.cpp \
src/qt/askpassphrasedialog.cpp \
src/protocol.cpp \
src/qt/notificator.cpp
src/qt/notificator.cpp \
src/qt/qtipcserver.cpp
RESOURCES += \
src/qt/bitcoin.qrc
@@ -190,6 +220,7 @@ RESOURCES += \
FORMS += \
src/qt/forms/sendcoinsdialog.ui \
src/qt/forms/addressbookpage.ui \
src/qt/forms/messagepage.ui \
src/qt/forms/aboutdialog.ui \
src/qt/forms/editaddressdialog.ui \
src/qt/forms/transactiondescdialog.ui \
@@ -197,6 +228,22 @@ FORMS += \
src/qt/forms/sendcoinsentry.ui \
src/qt/forms/askpassphrasedialog.ui
contains(USE_QRCODE, 1) {
HEADERS += src/qt/qrcodedialog.h
SOURCES += src/qt/qrcodedialog.cpp
FORMS += src/qt/forms/qrcodedialog.ui
}
contains(BITCOIN_QT_TEST, 1) {
SOURCES += src/qt/test/test_main.cpp \
src/qt/test/uritests.cpp
HEADERS += src/qt/test/uritests.h
DEPENDPATH += src/qt/test
QT += testlib
TARGET = bitcoin-qt_test
DEFINES += BITCOIN_QT_TEST
}
CODECFORTR = UTF-8
# for lrelease/lupdate
@@ -204,7 +251,7 @@ CODECFORTR = UTF-8
TRANSLATIONS = $$files(src/qt/locale/bitcoin_*.ts)
isEmpty(QMAKE_LRELEASE) {
win32:QMAKE_LRELEASE = $$[QT_INSTALL_BINS]\lrelease.exe
win32:QMAKE_LRELEASE = $$[QT_INSTALL_BINS]\\lrelease.exe
else:QMAKE_LRELEASE = $$[QT_INSTALL_BINS]/lrelease
}
isEmpty(TS_DIR):TS_DIR = src/qt/locale
@@ -219,7 +266,7 @@ PRE_TARGETDEPS += compiler_TSQM_make_all
# "Other files" to show in Qt Creator
OTHER_FILES += \
doc/*.rst doc/*.txt doc/README README.md
doc/*.rst doc/*.txt doc/README README.md res/bitcoin-qt.rc
# platform specific defaults, if not overridden on command line
isEmpty(BOOST_LIB_SUFFIX) {
@@ -251,10 +298,26 @@ isEmpty(BOOST_INCLUDE_PATH) {
macx:BOOST_INCLUDE_PATH = /opt/local/include
}
windows:LIBS += -lws2_32
windows:LIBS += -lws2_32 -lshlwapi
windows:DEFINES += WIN32
windows:RC_FILE = src/qt/res/bitcoin-qt.rc
windows:!contains(MINGW_THREAD_BUGFIX, 0) {
# At least qmake's win32-g++-cross profile is missing the -lmingwthrd
# thread-safety flag. GCC has -mthreads to enable this, but it doesn't
# work with static linking. -lmingwthrd must come BEFORE -lmingw, so
# it is prepended to QMAKE_LIBS_QT_ENTRY.
# It can be turned off with MINGW_THREAD_BUGFIX=0, just in case it causes
# any problems on some untested qmake profile now or in the future.
DEFINES += _MT
QMAKE_LIBS_QT_ENTRY = -lmingwthrd $$QMAKE_LIBS_QT_ENTRY
}
!windows:!mac {
DEFINES += LINUX
LIBS += -lrt
}
macx:HEADERS += src/qt/macdockiconhandler.h
macx:OBJECTIVE_SOURCES += src/qt/macdockiconhandler.mm
macx:LIBS += -framework Foundation -framework ApplicationServices -framework AppKit
@@ -263,11 +326,11 @@ macx:ICON = src/qt/res/icons/bitcoin.icns
macx:TARGET = "Bitcoin-Qt"
# Set libraries and includes at end, to use platform-defined defaults if not overridden
INCLUDEPATH += $$BOOST_INCLUDE_PATH $$BDB_INCLUDE_PATH $$OPENSSL_INCLUDE_PATH
LIBS += $$join(BOOST_LIB_PATH,,-L,) $$join(BDB_LIB_PATH,,-L,) $$join(OPENSSL_LIB_PATH,,-L,)
INCLUDEPATH += $$BOOST_INCLUDE_PATH $$BDB_INCLUDE_PATH $$OPENSSL_INCLUDE_PATH $$QRENCODE_INCLUDE_PATH
LIBS += $$join(BOOST_LIB_PATH,,-L,) $$join(BDB_LIB_PATH,,-L,) $$join(OPENSSL_LIB_PATH,,-L,) $$join(QRENCODE_LIB_PATH,,-L,)
LIBS += -lssl -lcrypto -ldb_cxx$$BDB_LIB_SUFFIX
# -lgdi32 has to happen after -lcrypto (see #681)
windows:LIBS += -lgdi32
windows:LIBS += -lole32 -luuid -lgdi32
LIBS += -lboost_system$$BOOST_LIB_SUFFIX -lboost_filesystem$$BOOST_LIB_SUFFIX -lboost_program_options$$BOOST_LIB_SUFFIX -lboost_thread$$BOOST_THREAD_LIB_SUFFIX
contains(RELEASE, 1) {

View File

@@ -2,10 +2,11 @@
Encoding=UTF-8
Name=Bitcoin
Comment=Bitcoin P2P Cryptocurrency
Comment[fr]=Bitcoin, monnaie virtuelle cryptographique pair à pair
Comment[tr]=Bitcoin, eşten eşe kriptografik sanal para birimi
Exec=/usr/bin/bitcoin-qt
Terminal=false
Type=Application
Icon=/usr/share/pixmaps/bitcoin80.xpm
#For when bitcoin (finally) properly handles bitcoin: URLs
#MimeType=x-scheme-handler/bitcoin;
MimeType=x-scheme-handler/bitcoin;
Categories=Office;

View File

@@ -3,3 +3,4 @@ bitcoin-qt usr/lib/bitcoin
share/pixmaps/bitcoin32.xpm usr/share/pixmaps
share/pixmaps/bitcoin80.xpm usr/share/pixmaps
debian/bitcoin-qt.desktop usr/share/applications
debian/bitcoin-qt.protocol usr/share/kde4/services/

View File

@@ -0,0 +1,11 @@
[Protocol]
exec=bitcoin-qt '%u'
protocol=bitcoin
input=none
output=none
helper=true
listing=
reading=false
writing=false
makedir=false
deleting=false

View File

@@ -1,3 +1,20 @@
bitcoin (0.5.1-natty1) natty; urgency=low
* Remove mentions on anonymity in package descriptions and manpage.
These should never have been there, bitcoin isnt anonymous without
a ton of work that virtually no users will ever be willing and
capable of doing
* Add GNOME/KDE support for bitcoin-qt's bitcoin: URI support.
Thanks to luke-jr for the KDE .protocol file.
-- Matt Corallo <matt@bluematt.me> Fri, 23 Dec 2011 20:25:00 -0500
bitcoin (0.5.1-natty0) natty; urgency=low
* New upstream release.
-- Matt Corallo <matt@bluematt.me> Fri, 16 Dec 2011 13:27:00 -0500
bitcoin (0.5.0-natty0) natty; urgency=low
* New upstream release.

View File

@@ -15,7 +15,8 @@ Build-Depends: debhelper,
libboost-thread-dev (>> 1.35) | libboost-thread1.35-dev,
libboost-test-dev (>> 1.35) | libboost-test1.35-dev,
qt4-qmake,
libqt4-dev
libqt4-dev,
libqrencode-dev
Standards-Version: 3.9.2
Homepage: http://www.bitcoin.org/
Vcs-Git: git://github.com/bitcoin/bitcoin.git
@@ -24,7 +25,7 @@ Vcs-Browser: http://github.com/bitcoin/bitcoin
Package: bitcoind
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}
Description: peer-to-peer network based anonymous digital currency - daemon
Description: peer-to-peer network based digital currency - daemon
Bitcoin is a free open source peer-to-peer electronic cash system that
is completely decentralized, without the need for a central server or
trusted parties. Users hold the crypto keys to their own money and
@@ -42,7 +43,7 @@ Description: peer-to-peer network based anonymous digital currency - daemon
Package: bitcoin-qt
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}
Description: peer-to-peer network based anonymous digital currency - QT GUI
Description: peer-to-peer network based digital currency - QT GUI
Bitcoin is a free open source peer-to-peer electronic cash system that
is completely decentralized, without the need for a central server or
trusted parties. Users hold the crypto keys to their own money and

View File

@@ -37,7 +37,7 @@ Files: src/qt/res/icons/address-book.png, src/qt/res/icons/export.png,
src/qt/res/icons/history.png, src/qt/res/icons/key.png,
src/qt/res/icons/lock_*.png, src/qt/res/icons/overview.png,
src/qt/res/icons/receive.png, src/qt/res/icons/send.png,
src/qt/res/icons/synced.png
src/qt/res/icons/synced.png, src/qt/res/icons/filesave.png
Copyright: David Vignoni (david@icon-king.com)
ICON KING - www.icon-king.com
License: LGPL

View File

@@ -1,6 +1,6 @@
.TH BITCOIND "1" "January 2011" "bitcoind 3.19"
.SH NAME
bitcoind \- peer-to-peer network based anonymous digital currency
bitcoind \- peer-to-peer network based digital currency
.SH SYNOPSIS
bitcoin [options] <command> [params]
.TP

View File

@@ -20,7 +20,7 @@ override_dh_auto_clean:
cd src; $(MAKE) -f makefile.unix clean
override_dh_auto_configure:
qmake bitcoin-qt.pro
qmake bitcoin-qt.pro USE_QRCODE=1
override_dh_auto_test:
cd src; $(MAKE) -f makefile.unix test_bitcoin

View File

@@ -0,0 +1,71 @@
---
name: "bitcoin-deps"
suites:
- "lucid"
architectures:
- "i386"
packages:
- "mingw32"
- "git-core"
- "zip"
- "faketime"
- "wine"
reference_datetime: "2011-01-30 00:00:00"
remotes: []
files:
- "openssl-1.0.1b.tar.gz"
- "db-4.8.30.NC.tar.gz"
- "miniupnpc-1.6.tar.gz"
- "zlib-1.2.6.tar.gz"
- "libpng-1.5.9.tar.gz"
- "qrencode-3.2.0.tar.bz2"
script: |
#
export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1
export FAKETIME=$REFERENCE_DATETIME
export TZ=UTC
#
tar xzf openssl-1.0.1b.tar.gz
cd openssl-1.0.1b
./Configure --cross-compile-prefix=i586-mingw32msvc- mingw
make
cd ..
#
tar xzf db-4.8.30.NC.tar.gz
cd db-4.8.30.NC/build_unix
../dist/configure --enable-mingw --enable-cxx --host=i586-mingw32msvc CFLAGS="-I/usr/i586-mingw32msvc/include"
make $MAKEOPTS
cd ../..
#
tar xzf miniupnpc-1.6.tar.gz
cd miniupnpc-1.6
sed 's/dllwrap -k --driver-name gcc/$(DLLWRAP) -k --driver-name $(CC)/' -i Makefile.mingw
sed 's|wingenminiupnpcstrings $< $@|./wingenminiupnpcstrings $< $@|' -i Makefile.mingw
make -f Makefile.mingw DLLWRAP=i586-mingw32msvc-dllwrap CC=i586-mingw32msvc-gcc AR=i586-mingw32msvc-ar
cd ..
mv miniupnpc-1.6 miniupnpc
#
tar xzf zlib-1.2.6.tar.gz
cd zlib-1.2.6
make -f win32/Makefile.gcc PREFIX=i586-mingw32msvc- $MAKEOPTS
cd ..
#
tar xzf libpng-1.5.9.tar.gz
cd libpng-1.5.9
./configure -disable-shared CC=i586-mingw32msvc-cc AR=i586-mingw32msvc-ar STRIP=i586-mingw32msvc-strip RANLIB=i586-mingw32msvc-ranlib OBJDUMP=i586-mingw32msvc-objdump LD=i586-mingw32msvc-ld LDFLAGS="-L../zlib-1.2.6/" CFLAGS="-I../zlib-1.2.6/"
make $MAKEOPTS
cd ..
#
tar xjf qrencode-3.2.0.tar.bz2
cd qrencode-3.2.0
./configure CC=i586-mingw32msvc-cc AR=i586-mingw32msvc-ar STRIP=i586-mingw32msvc-strip RANLIB=i586-mingw32msvc-ranlib OBJDUMP=i586-mingw32msvc-objdump LD=i586-mingw32msvc-ld png_LIBS="../libpng-1.5.9/.libs/libpng15.a ../zlib-1.2.6/libz.a" png_CFLAGS="-I../libpng-1.5.9"
make $MAKEOPTS
cd ..
#
zip -r $OUTDIR/bitcoin-deps-0.0.4.zip \
$(ls qrencode-*/{qrencode.h,.libs/libqrencode.{,l}a} | sort) \
$(ls db-*/build_unix/{libdb_cxx.a,db.h,db_cxx.h,libdb.a,.libs/libdb_cxx-?.?.a} | sort) \
$(find openssl-* -name '*.a' -o -name '*.h' | sort) \
$(find miniupnpc -name '*.h' -o -name 'libminiupnpc.a' | sort)
# Kill wine processes as gitian won't figure out we are done otherwise
killall wineserver services.exe explorer.exe winedevice.exe

View File

@@ -10,7 +10,6 @@ packages:
- "unzip"
- "nsis"
- "faketime"
- "wine"
reference_datetime: "2011-01-30 00:00:00"
remotes:
- "url": "https://github.com/bitcoin/bitcoin.git"
@@ -18,9 +17,7 @@ remotes:
files:
- "qt-win32-4.7.4-gitian.zip"
- "boost-win32-1.47.0-gitian.zip"
- "openssl-1.0.0e.tar.gz"
- "db-4.8.30.NC.tar.gz"
- "miniupnpc-1.6.tar.gz"
- "bitcoin-deps-0.0.4.zip"
script: |
#
mkdir $HOME/qt
@@ -42,47 +39,36 @@ script: |
mv include/boost .
cd ..
#
tar xzf openssl-1.0.0e.tar.gz
cd openssl-1.0.0e
./Configure --cross-compile-prefix=i586-mingw32msvc- mingw
make
cd ..
unzip bitcoin-deps-0.0.4.zip
#
tar xzf db-4.8.30.NC.tar.gz
cd db-4.8.30.NC/build_unix
../dist/configure --enable-mingw --enable-cxx --host=i586-mingw32msvc CFLAGS="-I/usr/i586-mingw32msvc/include"
make $MAKEOPTS
cd ../..
#
tar xzf miniupnpc-1.6.tar.gz
cd miniupnpc-1.6
sed 's/dllwrap -k --driver-name gcc/$(DLLWRAP) -k --driver-name $(CC)/' -i Makefile.mingw
sed 's|wingenminiupnpcstrings $< $@|./wingenminiupnpcstrings $< $@|' -i Makefile.mingw
make -f Makefile.mingw DLLWRAP=i586-mingw32msvc-dllwrap CC=i586-mingw32msvc-gcc AR=i586-mingw32msvc-ar
cd ..
mv miniupnpc-1.6 miniupnpc
find -type f | xargs touch --date="$REFERENCE_DATETIME"
#
cd bitcoin
mkdir -p $OUTDIR/src
cp -a . $OUTDIR/src
rm -rf $OUTDIR/src/.git
git archive HEAD | tar -x -C $OUTDIR/src
cp $OUTDIR/src/doc/README_windows.txt $OUTDIR/readme.txt
cp $OUTDIR/src/COPYING $OUTDIR/license.txt
export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1
export FAKETIME=$REFERENCE_DATETIME
export TZ=UTC
$HOME/qt/src/bin/qmake -spec unsupported/win32-g++-cross USE_SSL=1 MINIUPNPC_LIB_PATH=$HOME/build/miniupnpc MINIUPNPC_INCLUDE_PATH=$HOME/build/ BDB_LIB_PATH=$HOME/build/db-4.8.30.NC/build_unix BDB_INCLUDE_PATH=$HOME/build/db-4.8.30.NC/build_unix BOOST_LIB_PATH=$HOME/build/boost_1_47_0/stage/lib BOOST_INCLUDE_PATH=$HOME/build/boost_1_47_0 BOOST_LIB_SUFFIX=-mt-s BOOST_THREAD_LIB_SUFFIX=_win32-mt-s OPENSSL_LIB_PATH=$HOME/build/openssl-1.0.0e OPENSSL_INCLUDE_PATH=$HOME/build/openssl-1.0.0e/include INCLUDEPATH=$HOME/build DEFINES=BOOST_THREAD_USE_LIB BITCOIN_NEED_QT_PLUGINS=1 QMAKE_LRELEASE=lrelease QMAKE_CXXFLAGS=-frandom-seed=bitcoin QMAKE_LFLAGS=-frandom-seed=bitcoin
$HOME/qt/src/bin/qmake -spec unsupported/win32-g++-cross MINIUPNPC_LIB_PATH=$HOME/build/miniupnpc MINIUPNPC_INCLUDE_PATH=$HOME/build/ BDB_LIB_PATH=$HOME/build/db-4.8.30.NC/build_unix BDB_INCLUDE_PATH=$HOME/build/db-4.8.30.NC/build_unix BOOST_LIB_PATH=$HOME/build/boost_1_47_0/stage/lib BOOST_INCLUDE_PATH=$HOME/build/boost_1_47_0 BOOST_LIB_SUFFIX=-mt-s BOOST_THREAD_LIB_SUFFIX=_win32-mt-s OPENSSL_LIB_PATH=$HOME/build/openssl-1.0.1b OPENSSL_INCLUDE_PATH=$HOME/build/openssl-1.0.1b/include QRENCODE_LIB_PATH=$HOME/build/qrencode-3.2.0/.libs QRENCODE_INCLUDE_PATH=$HOME/build/qrencode-3.2.0 USE_QRCODE=1 INCLUDEPATH=$HOME/build DEFINES=BOOST_THREAD_USE_LIB BITCOIN_NEED_QT_PLUGINS=1 QMAKE_LRELEASE=lrelease QMAKE_CXXFLAGS=-frandom-seed=bitcoin QMAKE_LFLAGS=-frandom-seed=bitcoin USE_BUILD_INFO=1
make $MAKEOPTS
cp release/bitcoin-qt.exe $OUTDIR/
#
cd src
sed 's/$(DEBUGFLAGS)/-frandom-seed=bitcoin/' -i makefile.linux-mingw
export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1
export FAKETIME=$REFERENCE_DATETIME
export TZ=UTC
make -f makefile.linux-mingw $MAKEOPTS DEPSDIR=$HOME/build bitcoind.exe USE_SSL=1 USE_UPNP=0
make -f makefile.linux-mingw $MAKEOPTS DEPSDIR=$HOME/build bitcoind.exe USE_UPNP=0 DEBUGFLAGS="-frandom-seed=bitcoin"
i586-mingw32msvc-strip bitcoind.exe
makensis ../share/setup.nsi
cp ../share/bitcoin-*-win32-setup.exe $OUTDIR/
mkdir $OUTDIR/daemon
cp bitcoind.exe $OUTDIR/daemon
cd ..
mkdir nsis
git archive HEAD | tar -x -C nsis
cd nsis/src
mkdir ../release
cp ../../release/* ../release/
cp ../../src/*.exe .
makensis ../share/setup.nsi
cp ../share/bitcoin-*-win32-setup.exe $OUTDIR/

View File

@@ -16,12 +16,15 @@ packages:
- "libssl-dev"
- "git-core"
- "unzip"
- "pkg-config"
- "libpng12-dev"
reference_datetime: "2011-01-30 00:00:00"
remotes:
- "url": "https://github.com/bitcoin/bitcoin.git"
"dir": "bitcoin"
files:
- "miniupnpc-1.6.tar.gz"
- "qrencode-3.2.0.tar.bz2"
script: |
INSTDIR="$HOME/install"
export LIBRARY_PATH="$INSTDIR/lib"
@@ -31,18 +34,22 @@ script: |
INSTALLPREFIX=$INSTDIR make $MAKEOPTS install
cd ..
#
tar xjf qrencode-3.2.0.tar.bz2
cd qrencode-3.2.0
./configure --prefix=$INSTDIR --enable-static --disable-shared
make $MAKEOPTS install
cd ..
#
cd bitcoin
mkdir -p $OUTDIR/src
cp -a . $OUTDIR/src
rm -rf $OUTDIR/src/.git
git archive HEAD | tar -x -C $OUTDIR/src
cp $OUTDIR/src/doc/README $OUTDIR
cp $OUTDIR/src/COPYING $OUTDIR
cd src
sed 's/$(DEBUGFLAGS)//' -i makefile.unix
make -f makefile.unix STATIC=1 DEFS="-I$INSTDIR/include -L$INSTDIR/lib" $MAKEOPTS bitcoind USE_UPNP=0 USE_SSL=1
make -f makefile.unix STATIC=1 OPENSSL_INCLUDE_PATH="$INSTDIR/include" OPENSSL_LIB_PATH="$INSTDIR/lib" $MAKEOPTS bitcoind USE_UPNP=0 DEBUGFLAGS=
mkdir -p $OUTDIR/bin/$GBUILD_BITS
install -s bitcoind $OUTDIR/bin/$GBUILD_BITS
cd ..
qmake INCLUDEPATH="$INSTDIR/include" LIBS="-L$INSTDIR/lib" RELEASE=1 USE_SSL=1
qmake INCLUDEPATH="$INSTDIR/include" LIBS="-L$INSTDIR/lib" RELEASE=1 USE_QRCODE=1
make $MAKEOPTS
install bitcoin-qt $OUTDIR/bin/$GBUILD_BITS

View File

@@ -0,0 +1,28 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: SKS 1.1.0
mQENBE5UtMEBCADOUz2i9l/D8xYINCmfUDnxi+DXvX5LmZ39ZdvsoE+ugO0SRRGdIHEFO2is
0xezX50wXu9aneb+tEqM0BuiLo6VxaXpxrkxHpr6c4jf37SkE/H0qsi/txEUp7337y3+4HMG
lUjiuh802I72p1qusjsKBnmnnR0rwNouTcoDmGUDh7jpKCtzFv+2TR2dRthJn7vmmjq3+bG6
PYfqoFY1yHrAGT1lrDBULZsQ/NBLI2+J4oo2LYv3GCq8GNnzrovqvTvui50VSROhLrOe58o2
shE+sjQShAy5wYkPt1R1fQnpfx+5vf+TPnkxVwRb3h5GhCp0YL8XC/BXsd5vM4KlVH2rABEB
AAG0K1dsYWRpbWlyIEouIHZhbiBkZXIgTGFhbiA8bGFhbndqQGdtYWlsLmNvbT6JATgEEwEC
ACIFAk5UtMECGwMGCwkIBwMCBhUIAgkKCwQWAgMBAh4BAheAAAoJEHSBCwEjRsmmy6YIAK09
buNXyYQrJBsX16sXxEhx5QPKyF3uHJDFJv66SdnpvIkNoznsaPiRJkbTANop93FZmaGa6wVn
zGDiz7jPA8Dpxx5aAYPhIT+zPJAdXWM3wJ/Gio9besRNzniai8Lwi5MZ9R/5yFGBobm6/AcN
4sUoqA3NSV2U3I29R0Vwlzo8GVtmyi9ENSi6Oo7AcXNTRt69cxW4nAHkB+amwwDJlcAb31ex
bogYXPhScwqQZixRr+JBkKxBjkTXXnQypT4KI5SegYwQVYfyiZmDP7UHKe/u6pSKKbVphLg8
xLB5spcXse8/a2+onrbNlw6y8TXiJ++Z54PE7zztWTXf2huakeG5AQ0ETlS0wQEIAMNO3OkP
xoPRKWzBLcI7JRITAW+HNaLTq3uN2+4WxA57DEjbL9EDoAv+7wTkDAL40f0T+xiu6GJcLFjw
GJZu/tYu7+mErHjrdo+K4suCQt7w5EXCBvOLjhW4tyYMzNx8hP+oqzOW9iEC+6VV91+DYeqt
EkJuyVXOI4vzBlTw8uGow8aMMsCq8XVvKUZFTPsjGl197Q5B3A+ZOFCR8xqiqdPjuz6MglVV
oFdDNu3EZn8zkGsQlovXoE9ndVeVzx/XMNmsxFaMYsReUs253RIf1FEfgExID0fg2OnyLCjS
2iFW1RgajS+/saIkKl+N1iuMzJA7wMAM0plhRueOG0MtZSsAEQEAAYkBHwQYAQIACQUCTlS0
wQIbDAAKCRB0gQsBI0bJpmsDB/4waenn2CvSHXyomykfpwf5lMte1V5LvH3z5R2LY+1NopRv
LSz3iC39x69XWiTbhywDfgafnGPW4pWBOff2/bu5/A6z1Hnan1vyrRRD/hx1uMJ7S6q+bIvZ
iVIg1p0jH6tdIIhwX3cydhdRZHo7e9oSMgOUWsr6Ar59NRo9CENwGPE4U61HXfOnxWdrFWoA
XdwZczBeLxmUy6Vo6sKqv+gE4bqrtAM0sY/MsQ9cU95x+52ox/sq44lQMwd3ZBYUP7B1qbHI
hZSZuch6MLi5scLPeau0ZvCaljiaMeivP5+x0gWPRs0kI+9sZxInbqvrsJ6oOBJM3xYGhtn1
zZ7qmZR7
=si/k
-----END PGP PUBLIC KEY BLOCK-----

View File

@@ -15,9 +15,13 @@ signers:
weight: 40
name: Devrandom
key: devrandom
E463A93F5F3117EEDE6C7316BD02942421F4889F:
weight: 40
name: Luke-Jr
key: luke-jr
D762373D24904A3E42F33B08B9A408E71DAAC974:
weight: 40
name: Sipa
name: "Pieter Wuille"
key: sipa
77E72E69DA7EE0A148C06B21B34821D4944DE5F7:
weight: 40
@@ -27,4 +31,8 @@ signers:
weight: 40
name: "Gavin Andresen"
key: gavinandresen
71A3B16735405025D447E8F274810B012346C9A6
weight: 40
name: "Wladimir J. van der Laan"
key: laanwj
minimum_weight: 120

Binary file not shown.

View File

@@ -15,9 +15,13 @@ signers:
weight: 40
name: Devrandom
key: devrandom
E463A93F5F3117EEDE6C7316BD02942421F4889F:
weight: 40
name: Luke-Jr
key: luke-jr
D762373D24904A3E42F33B08B9A408E71DAAC974:
weight: 40
name: Sipa
name: "Pieter Wuille"
key: sipa
77E72E69DA7EE0A148C06B21B34821D4944DE5F7:
weight: 40
@@ -27,4 +31,8 @@ signers:
weight: 40
name: "Gavin Andresen"
key: gavinandresen
71A3B16735405025D447E8F274810B012346C9A6
weight: 40
name: "Wladimir J. van der Laan"
key: laanwj
minimum_weight: 120

View File

@@ -17,16 +17,405 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
import subprocess, sys, re, os, shutil, os.path
import subprocess, sys, re, os, shutil, stat, os.path
from time import sleep
from argparse import ArgumentParser
# This is ported from the original macdeployqt with modifications
class FrameworkInfo(object):
def __init__(self):
self.frameworkDirectory = ""
self.frameworkName = ""
self.frameworkPath = ""
self.binaryDirectory = ""
self.binaryName = ""
self.binaryPath = ""
self.version = ""
self.installName = ""
self.deployedInstallName = ""
self.sourceFilePath = ""
self.destinationDirectory = ""
self.sourceResourcesDirectory = ""
self.destinationResourcesDirectory = ""
def __eq__(self, other):
if self.__class__ == other.__class__:
return self.__dict__ == other.__dict__
else:
return False
def __str__(self):
return """ Framework name: %s
Framework directory: %s
Framework path: %s
Binary name: %s
Binary directory: %s
Binary path: %s
Version: %s
Install name: %s
Deployed install name: %s
Source file Path: %s
Deployed Directory (relative to bundle): %s
""" % (self.frameworkName,
self.frameworkDirectory,
self.frameworkPath,
self.binaryName,
self.binaryDirectory,
self.binaryPath,
self.version,
self.installName,
self.deployedInstallName,
self.sourceFilePath,
self.destinationDirectory)
def isDylib(self):
return self.frameworkName.endswith(".dylib")
def isQtFramework(self):
if self.isDylib():
return self.frameworkName.startswith("libQt")
else:
return self.frameworkName.startswith("Qt")
reOLine = re.compile(r'^(.+) \(compatibility version [0-9.]+, current version [0-9.]+\)$')
bundleFrameworkDirectory = "Contents/Frameworks"
bundleBinaryDirectory = "Contents/MacOS"
@classmethod
def fromOtoolLibraryLine(cls, line):
# Note: line must be trimmed
if line == "":
return None
# Don't deploy system libraries (exception for libQtuitools and libQtlucene).
if line.startswith("/System/Library/") or line.startswith("@executable_path") or (line.startswith("/usr/lib/") and "libQt" not in line):
return None
m = cls.reOLine.match(line)
if m is None:
raise RuntimeError("otool line could not be parsed: " + line)
path = m.group(1)
info = cls()
info.sourceFilePath = path
info.installName = path
if path.endswith(".dylib"):
dirname, filename = os.path.split(path)
info.frameworkName = filename
info.frameworkDirectory = dirname
info.frameworkPath = path
info.binaryDirectory = dirname
info.binaryName = filename
info.binaryPath = path
info.version = "-"
info.installName = path
info.deployedInstallName = "@executable_path/../Frameworks/" + info.binaryName
info.sourceFilePath = path
info.destinationDirectory = cls.bundleFrameworkDirectory
else:
parts = path.split("/")
i = 0
# Search for the .framework directory
for part in parts:
if part.endswith(".framework"):
break
i += 1
if i == len(parts):
raise RuntimeError("Could not find .framework or .dylib in otool line: " + line)
info.frameworkName = parts[i]
info.frameworkDirectory = "/".join(parts[:i])
info.frameworkPath = os.path.join(info.frameworkDirectory, info.frameworkName)
info.binaryName = parts[i+3]
info.binaryDirectory = "/".join(parts[i+1:i+3])
info.binaryPath = os.path.join(info.binaryDirectory, info.binaryName)
info.version = parts[i+2]
info.deployedInstallName = "@executable_path/../Frameworks/" + os.path.join(info.frameworkName, info.binaryPath)
info.destinationDirectory = os.path.join(cls.bundleFrameworkDirectory, info.frameworkName, info.binaryDirectory)
info.sourceResourcesDirectory = os.path.join(info.frameworkPath, "Resources")
info.destinationResourcesDirectory = os.path.join(cls.bundleFrameworkDirectory, info.frameworkName, "Resources")
return info
class ApplicationBundleInfo(object):
def __init__(self, path):
self.path = path
appName = os.path.splitext(os.path.basename(path))[0]
self.binaryPath = os.path.join(path, "Contents", "MacOS", appName)
if not os.path.exists(self.binaryPath):
raise RuntimeError("Could not find bundle binary for " + path)
self.resourcesPath = os.path.join(path, "Contents", "Resources")
self.pluginPath = os.path.join(path, "Contents", "PlugIns")
class DeploymentInfo(object):
def __init__(self):
self.qtPath = None
self.pluginPath = None
self.deployedFrameworks = []
def detectQtPath(self, frameworkDirectory):
parentDir = os.path.dirname(frameworkDirectory)
if os.path.exists(os.path.join(parentDir, "translations")):
# Classic layout, e.g. "/usr/local/Trolltech/Qt-4.x.x"
self.qtPath = parentDir
elif os.path.exists(os.path.join(parentDir, "share", "qt4", "translations")):
# MacPorts layout, e.g. "/opt/local/share/qt4"
self.qtPath = os.path.join(parentDir, "share", "qt4")
if self.qtPath is not None:
pluginPath = os.path.join(self.qtPath, "plugins")
if os.path.exists(pluginPath):
self.pluginPath = pluginPath
def usesFramework(self, name):
nameDot = "%s." % name
libNameDot = "lib%s." % name
for framework in self.deployedFrameworks:
if framework.endswith(".framework"):
if framework.startswith(nameDot):
return True
elif framework.endswith(".dylib"):
if framework.startswith(libNameDot):
return True
return False
def getFrameworks(binaryPath, verbose):
if verbose >= 3:
print "Inspecting with otool: " + binaryPath
otool = subprocess.Popen(["otool", "-L", binaryPath], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
o_stdout, o_stderr = otool.communicate()
if otool.returncode != 0:
if verbose >= 1:
sys.stderr.write(o_stderr)
sys.stderr.flush()
raise RuntimeError("otool failed with return code %d" % otool.returncode)
otoolLines = o_stdout.split("\n")
otoolLines.pop(0) # First line is the inspected binary
if ".framework" in binaryPath or binaryPath.endswith(".dylib"):
otoolLines.pop(0) # Frameworks and dylibs list themselves as a dependency.
libraries = []
for line in otoolLines:
info = FrameworkInfo.fromOtoolLibraryLine(line.strip())
if info is not None:
if verbose >= 3:
print "Found framework:"
print info
libraries.append(info)
return libraries
def runInstallNameTool(action, *args):
subprocess.check_call(["install_name_tool", "-"+action] + list(args))
def changeInstallName(oldName, newName, binaryPath, verbose):
if verbose >= 3:
print "Using install_name_tool:"
print " in", binaryPath
print " change reference", oldName
print " to", newName
runInstallNameTool("change", oldName, newName, binaryPath)
def changeIdentification(id, binaryPath, verbose):
if verbose >= 3:
print "Using install_name_tool:"
print " change identification in", binaryPath
print " to", id
runInstallNameTool("id", id, binaryPath)
def runStrip(binaryPath, verbose):
if verbose >= 3:
print "Using strip:"
print " stripped", binaryPath
subprocess.check_call(["strip", "-x", binaryPath])
def copyFramework(framework, path, verbose):
fromPath = framework.sourceFilePath
toDir = os.path.join(path, framework.destinationDirectory)
toPath = os.path.join(toDir, framework.binaryName)
if not os.path.exists(fromPath):
raise RuntimeError("No file at " + fromPath)
if os.path.exists(toPath):
return None # Already there
if not os.path.exists(toDir):
os.makedirs(toDir)
shutil.copy2(fromPath, toPath)
if verbose >= 3:
print "Copied:", fromPath
print " to:", toPath
permissions = os.stat(toPath)
if not permissions.st_mode & stat.S_IWRITE:
os.chmod(toPath, permissions.st_mode | stat.S_IWRITE)
if not framework.isDylib(): # Copy resources for real frameworks
fromResourcesDir = framework.sourceResourcesDirectory
if os.path.exists(fromResourcesDir):
toResourcesDir = os.path.join(path, framework.destinationResourcesDirectory)
shutil.copytree(fromResourcesDir, toResourcesDir)
if verbose >= 3:
print "Copied resources:", fromResourcesDir
print " to:", toResourcesDir
elif framework.frameworkName.startswith("libQtGui"): # Copy qt_menu.nib (applies to non-framework layout)
qtMenuNibSourcePath = os.path.join(framework.frameworkDirectory, "Resources", "qt_menu.nib")
qtMenuNibDestinationPath = os.path.join(path, "Contents", "Resources", "qt_menu.nib")
if os.path.exists(qtMenuNibSourcePath) and not os.path.exists(qtMenuNibDestinationPath):
shutil.copytree(qtMenuNibSourcePath, qtMenuNibDestinationPath)
if verbose >= 3:
print "Copied for libQtGui:", qtMenuNibSourcePath
print " to:", qtMenuNibDestinationPath
return toPath
def deployFrameworks(frameworks, bundlePath, binaryPath, strip, verbose, deploymentInfo=None):
if deploymentInfo is None:
deploymentInfo = DeploymentInfo()
while len(frameworks) > 0:
framework = frameworks.pop(0)
deploymentInfo.deployedFrameworks.append(framework.frameworkName)
if verbose >= 2:
print "Processing", framework.frameworkName, "..."
# Get the Qt path from one of the Qt frameworks
if deploymentInfo.qtPath is None and framework.isQtFramework():
deploymentInfo.detectQtPath(framework.frameworkDirectory)
if framework.installName.startswith("@executable_path"):
if verbose >= 2:
print framework.frameworkName, "already deployed, skipping."
continue
# install_name_tool the new id into the binary
changeInstallName(framework.installName, framework.deployedInstallName, binaryPath, verbose)
# Copy farmework to app bundle.
deployedBinaryPath = copyFramework(framework, bundlePath, verbose)
# Skip the rest if already was deployed.
if deployedBinaryPath is None:
continue
if strip:
runStrip(deployedBinaryPath, verbose)
# install_name_tool it a new id.
changeIdentification(framework.deployedInstallName, deployedBinaryPath, verbose)
# Check for framework dependencies
dependencies = getFrameworks(deployedBinaryPath, verbose)
for dependency in dependencies:
changeInstallName(dependency.installName, dependency.deployedInstallName, deployedBinaryPath, verbose)
# Deploy framework if necessary.
if dependency.frameworkName not in deploymentInfo.deployedFrameworks and dependency not in frameworks:
frameworks.append(dependency)
return deploymentInfo
def deployFrameworksForAppBundle(applicationBundle, strip, verbose):
frameworks = getFrameworks(applicationBundle.binaryPath, verbose)
if len(frameworks) == 0 and verbose >= 1:
print "Warning: Could not find any external frameworks to deploy in %s." % (applicationBundle.path)
return DeploymentInfo()
else:
return deployFrameworks(frameworks, applicationBundle.path, applicationBundle.binaryPath, strip, verbose)
def deployPlugins(appBundleInfo, deploymentInfo, strip, verbose):
# Lookup available plugins, exclude unneeded
plugins = []
for dirpath, dirnames, filenames in os.walk(deploymentInfo.pluginPath):
pluginDirectory = os.path.relpath(dirpath, deploymentInfo.pluginPath)
if pluginDirectory == "designer":
# Skip designer plugins
continue
elif pluginDirectory == "phonon":
# Deploy the phonon plugins only if phonon is in use
if not deploymentInfo.usesFramework("phonon"):
continue
elif pluginDirectory == "sqldrivers":
# Deploy the sql plugins only if QtSql is in use
if not deploymentInfo.usesFramework("QtSql"):
continue
elif pluginDirectory == "script":
# Deploy the script plugins only if QtScript is in use
if not deploymentInfo.usesFramework("QtScript"):
continue
elif pluginDirectory == "qmltooling":
# Deploy the qml plugins only if QtDeclarative is in use
if not deploymentInfo.usesFramework("QtDeclarative"):
continue
elif pluginDirectory == "bearer":
# Deploy the bearer plugins only if QtNetwork is in use
if not deploymentInfo.usesFramework("QtNetwork"):
continue
for pluginName in filenames:
pluginPath = os.path.join(pluginDirectory, pluginName)
if pluginName.endswith("_debug.dylib"):
# Skip debug plugins
continue
elif pluginPath == "imageformats/libqsvg.dylib" or pluginPath == "iconengines/libqsvgicon.dylib":
# Deploy the svg plugins only if QtSvg is in use
if not deploymentInfo.usesFramework("QtSvg"):
continue
elif pluginPath == "accessible/libqtaccessiblecompatwidgets.dylib":
# Deploy accessibility for Qt3Support only if the Qt3Support is in use
if not deploymentInfo.usesFramework("Qt3Support"):
continue
elif pluginPath == "graphicssystems/libqglgraphicssystem.dylib":
# Deploy the opengl graphicssystem plugin only if QtOpenGL is in use
if not deploymentInfo.usesFramework("QtOpenGL"):
continue
plugins.append((pluginDirectory, pluginName))
for pluginDirectory, pluginName in plugins:
if verbose >= 2:
print "Processing plugin", os.path.join(pluginDirectory, pluginName), "..."
sourcePath = os.path.join(deploymentInfo.pluginPath, pluginDirectory, pluginName)
destinationDirectory = os.path.join(appBundleInfo.pluginPath, pluginDirectory)
if not os.path.exists(destinationDirectory):
os.makedirs(destinationDirectory)
destinationPath = os.path.join(destinationDirectory, pluginName)
shutil.copy2(sourcePath, destinationPath)
if verbose >= 3:
print "Copied:", sourcePath
print " to:", destinationPath
if strip:
runStrip(destinationPath, verbose)
dependencies = getFrameworks(destinationPath, verbose)
for dependency in dependencies:
changeInstallName(dependency.installName, dependency.deployedInstallName, destinationPath, verbose)
# Deploy framework if necessary.
if dependency.frameworkName not in deploymentInfo.deployedFrameworks:
deployFrameworks([dependency], appBundleInfo.path, destinationPath, strip, verbose, deploymentInfo)
qt_conf="""[Paths]
translations=Resources
plugins=PlugIns
"""
ap = ArgumentParser(description="""Front-end to macdeployqt with some additional functions.
ap = ArgumentParser(description="""Improved version of macdeployqt.
Outputs a ready-to-deploy app in a folder "dist" and optionally wraps it in a .dmg file.
Note, that the "dist" folder will be deleted before deploying on each run.
@@ -69,22 +458,6 @@ for p in config.add_resources:
# ------------------------------------------------
if len(config.add_qt_tr) == 0:
add_qt_tr = []
else:
qt_tr_dir = os.path.join(os.getenv("QTDIR", ""), "translations")
add_qt_tr = ["qt_%s.qm" % lng for lng in config.add_qt_tr[0].split(",")]
for lng_file in add_qt_tr:
p = os.path.join(qt_tr_dir, lng_file)
if verbose >= 3:
print "Checking for \"%s\"..." % p
if not os.path.exists(p):
if verbose >= 1:
sys.stderr.write("Error: Could not find Qt translation file \"%s\"\n" % (lng_file))
sys.exit(1)
# ------------------------------------------------
if len(config.fancy) == 1:
if verbose >= 3:
print "Fancy: Importing plistlib..."
@@ -160,7 +533,6 @@ if os.path.exists("dist"):
# ------------------------------------------------
target = os.path.join("dist", app_bundle)
target_res = os.path.join(target, "Contents", "Resources")
if verbose >= 2:
print "+ Copying source bundle +"
@@ -170,27 +542,61 @@ if verbose >= 3:
os.mkdir("dist")
shutil.copytree(app_bundle, target)
applicationBundle = ApplicationBundleInfo(target)
# ------------------------------------------------
macdeployqt_args = ["macdeployqt", target, "-verbose=%d" % verbose]
if not config.plugins:
macdeployqt_args.append("-no-plugins")
if not config.strip:
macdeployqt_args.append("-no-strip")
if verbose >= 2:
print "+ Running macdeployqt +"
print "+ Deploying frameworks +"
ret = subprocess.call(macdeployqt_args)
if ret != 0:
try:
deploymentInfo = deployFrameworksForAppBundle(applicationBundle, config.strip, verbose)
if deploymentInfo.qtPath is None:
deploymentInfo.qtPath = os.getenv("QTDIR", None)
if deploymentInfo.qtPath is None:
if verbose >= 1:
sys.stderr.write("Warning: Could not detect Qt's path, skipping plugin deployment!\n")
config.plugins = False
except RuntimeError as e:
if verbose >= 1:
sys.stderr.write("Error: %s\n" % str(e))
sys.exit(ret)
# ------------------------------------------------
if config.plugins:
if verbose >= 2:
print "+ Deploying plugins +"
try:
deployPlugins(applicationBundle, deploymentInfo, config.strip, verbose)
except RuntimeError as e:
if verbose >= 1:
sys.stderr.write("Error: %s\n" % str(e))
sys.exit(ret)
# ------------------------------------------------
if len(config.add_qt_tr) == 0:
add_qt_tr = []
else:
qt_tr_dir = os.path.join(deploymentInfo.qtPath, "translations")
add_qt_tr = ["qt_%s.qm" % lng for lng in config.add_qt_tr[0].split(",")]
for lng_file in add_qt_tr:
p = os.path.join(qt_tr_dir, lng_file)
if verbose >= 3:
print "Checking for \"%s\"..." % p
if not os.path.exists(p):
if verbose >= 1:
sys.stderr.write("Error: Could not find Qt translation file \"%s\"\n" % (lng_file))
sys.exit(1)
# ------------------------------------------------
if verbose >= 2:
print "+ Installing qt.conf +"
f = open(os.path.join(target_res, "qt.conf"), "wb")
f = open(os.path.join(applicationBundle.resourcesPath, "qt.conf"), "wb")
f.write(qt_conf)
f.close()
@@ -201,8 +607,8 @@ if len(add_qt_tr) > 0 and verbose >= 2:
for lng_file in add_qt_tr:
if verbose >= 3:
print os.path.join(qt_tr_dir, lng_file), "->", os.path.join(target_res, lng_file)
shutil.copy2(os.path.join(qt_tr_dir, lng_file), os.path.join(target_res, lng_file))
print os.path.join(qt_tr_dir, lng_file), "->", os.path.join(applicationBundle.resourcesPath, lng_file)
shutil.copy2(os.path.join(qt_tr_dir, lng_file), os.path.join(applicationBundle.resourcesPath, lng_file))
# ------------------------------------------------
@@ -210,7 +616,7 @@ if len(config.add_resources) > 0 and verbose >= 2:
print "+ Adding additional resources +"
for p in config.add_resources:
t = os.path.join(target_res, os.path.basename(p))
t = os.path.join(applicationBundle.resourcesPath, os.path.basename(p))
if verbose >= 3:
print p, "->", t
if os.path.isdir(p):

View File

@@ -6,7 +6,7 @@ You will need the appscript package for the fancy disk image creation to work.
Install it by invoking "sudo easy_install appscript".
Ths script should be invoked in the target directory like this:
$source_dir/contrib/macdeploy/macdeployqtplus Bitcoin-Qt.app -add-qt-tr de,es,ru -dmg -fancy $source_dir/contrib/macdeploy/fancy.plist
$source_dir/contrib/macdeploy/macdeployqtplus Bitcoin-Qt.app -add-qt-tr da,de,es,hu,ru,uk,zh_CN,zh_TW -dmg -fancy $source_dir/contrib/macdeploy/fancy.plist -verbose 2
During the process, the disk image window will pop up briefly where the fancy
settings are applied. This is normal, please do not interfere.
@@ -19,7 +19,7 @@ Fill in the following.
Enable custom process step: [x]
Command: %{sourceDir}/contrib/macdeploy/macdeployqtplus
Working directory: %{buildDir}
Command arguments: Bitcoin-Qt.app -add-qt-tr de,ru -dmg -fancy %{sourceDir}/contrib/macdeploy/fancy.plist
Command arguments: Bitcoin-Qt.app -add-qt-tr da,de,es,hu,ru,uk,zh_CN,zh_TW -dmg -fancy %{sourceDir}/contrib/macdeploy/fancy.plist -verbose 2
After that you can start the deployment process through the menu with
Build -> Deploy Project "bitcoin-qt"

View File

@@ -1,43 +0,0 @@
# -*- coding: utf-8; mode: tcl; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- vim:fenc=utf-8:filetype=tcl:et:sw=4:ts=4:sts=4
# $Id$
PortSystem 1.0
name miniupnpc
epoch 2
version 1.6
revision 2
categories net
platforms darwin
license BSD
maintainers singingwolfboy openmaintainer
description Lightweight client for UPnP protocol
long_description \
${description}
homepage http://miniupnp.free.fr/
master_sites http://miniupnp.free.fr/files/download.php?file=${distname}${extract.suffix}&dummy=
checksums md5 88055f2d4a061cfd4cfe25a9eae22f67 \
sha1 ef8f2edb17f2e7c5b8dc67ee80a65c199d823e0a \
rmd160 d86b75b331a3fb5525c71708548f311977c0598f
use_configure no
variant universal {}
if {[variant_isset universal]} {
set archflags ${configure.universal_cflags}
} else {
set archflags ${configure.cc_archflags}
}
build.args-append CC="${configure.cc} ${archflags}"
post-patch {
reinplace "s|-Wl,-install_name,|-Wl,-install_name,${prefix}/lib/|" ${worksrcpath}/Makefile
}
destroot.destdir PREFIX=${prefix} INSTALLPREFIX=${destroot}${prefix}
livecheck.type regex
livecheck.url http://miniupnp.free.fr/files/
livecheck.regex ${name}-(\\d+(\\.\\d{1,4})+)${extract.suffix}

View File

@@ -1,6 +1,6 @@
Bitcoin 0.5.1 BETA
Bitcoin 0.6.1 BETA
Copyright (c) 2009-2011 Bitcoin Developers
Copyright (c) 2009-2012 Bitcoin Developers
Distributed under the MIT/X11 software license, see the accompanying
file license.txt or http://www.opensource.org/licenses/mit-license.php.
This product includes software developed by the OpenSSL Project for use in

View File

@@ -1,6 +1,6 @@
Bitcoin 0.5.1 BETA
Bitcoin 0.6.1 BETA
Copyright (c) 2009-2011 Bitcoin Developers
Copyright (c) 2009-2012 Bitcoin Developers
Distributed under the MIT/X11 software license, see the accompanying
file license.txt or http://www.opensource.org/licenses/mit-license.php.
This product includes software developed by the OpenSSL Project for use in

View File

@@ -1,3 +1,7 @@
Code: src/strlcpy.h
Author: Todd C. Miller <Todd.Miller@courtesan.com>
License: ISC
Icon: src/qt/res/icons/clock*.png, src/qt/res/icons/tx*.png,
src/qt/res/src/*.svg
Designer: Wladimir van der Laan
@@ -7,7 +11,7 @@ Icon: src/qt/res/icons/address-book.png, src/qt/res/icons/export.png,
src/qt/res/icons/history.png, src/qt/res/icons/key.png,
src/qt/res/icons/lock_*.png, src/qt/res/icons/overview.png,
src/qt/res/icons/receive.png, src/qt/res/icons/send.png,
src/qt/res/icons/synced.png
src/qt/res/icons/synced.png, src/qt/res/icons/filesave.png
Icon Pack: NUVOLA ICON THEME for KDE 3.x
Designer: David Vignoni (david@icon-king.com)
ICON KING - www.icon-king.com

View File

@@ -1,4 +1,4 @@
Copyright (c) 2009-2011 Bitcoin Developers
Copyright (c) 2009-2012 Bitcoin Developers
Distributed under the MIT/X11 software license, see the accompanying
file license.txt or http://www.opensource.org/licenses/mit-license.php.
This product includes software developed by the OpenSSL Project for use in
@@ -24,7 +24,7 @@ Dependencies
Libraries you need to download separately and build:
default path download
OpenSSL \openssl-1.0.0d-mgw http://www.openssl.org/source/
OpenSSL \openssl-1.0.1b-mgw http://www.openssl.org/source/
Berkeley DB \db-4.8.30.NC-mgw http://www.oracle.com/technology/software/products/berkeley-db/index.html
Boost \boost-1.47.0-mgw http://www.boost.org/users/download/
miniupnpc \miniupnpc-1.6-mgw http://miniupnp.tuxfamily.org/files/
@@ -36,7 +36,7 @@ Boost MIT-like license
miniupnpc New (3-clause) BSD license
Versions used in this release:
OpenSSL 1.0.0e
OpenSSL 1.0.1b
Berkeley DB 4.8.30.NC
Boost 1.47.0
miniupnpc 1.6
@@ -48,7 +48,7 @@ MSYS shell:
un-tar sources with MSYS 'tar xfz' to avoid issue with symlinks (OpenSSL ticket 2377)
change 'MAKE' env. variable from 'C:\MinGW32\bin\mingw32-make.exe' to '/c/MinGW32/bin/mingw32-make.exe'
cd /c/openssl-1.0.0e-mgw
cd /c/openssl-1.0.1b-mgw
./config
make

View File

@@ -1,4 +1,4 @@
Copyright (c) 2011 Bitcoin Developers
Copyright (c) 2009-2012 Bitcoin Developers
Distributed under the MIT/X11 software license, see the accompanying file
license.txt or http://www.opensource.org/licenses/mit-license.php. This
product includes software developed by the OpenSSL Project for use in the
@@ -36,12 +36,10 @@ git clone git@github.com:bitcoin/bitcoin.git bitcoin
3. Install dependencies from MacPorts
sudo port install boost db48 openssl
sudo port install boost db48 openssl miniupnpc
Install the right version of miniupnpc:
pushd bitcoin/contrib/minipupnpc; sudo port install; popd
(this will be unnecessary soon, you will just port install miniupnpc
along with the rest of the dependencies).
Optionally install qrencode (and set USE_QRCODE=1):
sudo port install qrencode
4. Now you should be able to build bitcoind:

View File

@@ -1,5 +1,4 @@
Copyright (c) 2009-2010 Satoshi Nakamoto
Copyright (c) 2011 Bitcoin Developers
Copyright (c) 2009-2012 Bitcoin Developers
Distributed under the MIT/X11 software license, see the accompanying
file license.txt or http://www.opensource.org/licenses/mit-license.php.
This product includes software developed by the OpenSSL Project for use in
@@ -23,12 +22,13 @@ the graphical bitcoin.
Dependencies
------------
Library Purpose Description
------- ------- -----------
libssl SSL Support Secure communications
libdb4.8 Berkeley DB Blockchain & wallet storage
libboost Boost C++ Library
miniupnpc UPnP Support Optional firewall-jumping support
Library Purpose Description
------- ------- -----------
libssl SSL Support Secure communications
libdb4.8 Berkeley DB Blockchain & wallet storage
libboost Boost C++ Library
miniupnpc UPnP Support Optional firewall-jumping support
libqrencode QRCode generation Optional QRCode generation
miniupnpc may be used for UPnP port mapping. It can be downloaded from
http://miniupnp.tuxfamily.org/files/. UPnP support is compiled in and
@@ -37,6 +37,12 @@ turned off by default. Set USE_UPNP to a different value to control this:
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=1 QRCode support enabled
Licenses of statically linked libraries:
Berkeley DB New BSD license with additional requirement that linked
software must be free open source
@@ -50,7 +56,6 @@ Versions used in this release:
Boost 1.37
miniupnpc 1.6
Dependency Build Instructions: Ubuntu & Debian
----------------------------------------------
sudo apt-get install build-essential
@@ -59,6 +64,7 @@ sudo apt-get install libdb4.8-dev
sudo apt-get install libdb4.8++-dev
Boost 1.40+: sudo apt-get install libboost-all-dev
or Boost 1.37: sudo apt-get install libboost1.37-dev
sudo apt-get install libqrencode-dev
If using Boost 1.37, append -mt to the boost libraries in the makefile.

View File

@@ -1,39 +1,6 @@
Bitcoin-qt: Qt4 GUI for Bitcoin
===============================
Features
========
- All functionality of the Wx GUI, including wallet encryption
- Compatibility with Linux (both GNOME and KDE), MacOSX and Windows
- Notification on incoming / outgoing transactions (compatible with FreeDesktop and other desktop notification schemes)
- General interface improvements: Splash screen, tabbed interface
- Overview page with current balance, unconfirmed balance, and such
- Better transaction list with status icons, real-time filtering and a context menu
- Asks for confirmation before sending coins, for your own safety
- CSV export of transactions and address book (for Excel bookkeeping)
- Shows alternative icon when connected to testnet, so you never accidentally send real coins during testing
- Shows a progress bar on initial block download, so that you don't have to wonder how many blocks it needs to download to be up to date
- Sendmany support, send to multiple recipients at the same time
- Multiple unit support, can show subdivided bitcoins (uBTC, mBTC) for users that like large numbers
- Support for English, German, Russian and Dutch languages
- Address books and transaction table can be sorted by any column
- Accepts "bitcoin:" URLs from browsers and other sources through drag and drop
Build instructions
===================
@@ -92,7 +59,7 @@ Mac OS X
::
sudo port selfupdate
sudo port install boost db48
sudo port install boost db48 miniupnpc
- Open the .pro file in Qt Creator and build as normal (cmd-B)
@@ -127,14 +94,6 @@ Set USE_UPNP to a different value to control this:
| USE_UPNP=1 | build with UPnP support turned on by default at runtime. |
+------------+--------------------------------------------------------------------------+
Mac OS X users: miniupnpc is currently outdated on MacPorts. An updated Portfile is provided in contrib/miniupnpc within this project.
You can execute the following commands in a terminal to install it:
::
cd <location of bitcoin-qt>/contrib/miniupnpc
sudo port install
Notification support for recent (k)ubuntu versions
---------------------------------------------------
@@ -145,6 +104,20 @@ FreeDesktop notification interface through DBUS using the following qmake option
qmake "USE_DBUS=1"
Generation of QR codes
-----------------------
libqrencode may be used to generate QRCode images for payment requests.
It can be downloaded from http://fukuchi.org/works/qrencode/index.html.en, or installed via your package manager. Pass the USE_QRCODE
flag to qmake to control this:
+--------------+--------------------------------------------------------------------------+
| USE_QRCODE=0 | (the default) No QRCode support - libarcode not required |
+--------------+--------------------------------------------------------------------------+
| USE_QRCODE=1 | QRCode support enabled |
+--------------+--------------------------------------------------------------------------+
Berkely DB version warning
==========================

View File

@@ -1,6 +1,8 @@
* update translations (ping tcatm on IRC for now)
* update (commit) version in sources
bitcoin-qt.pro
src/serialize.h
src/version.h
share/setup.nsi
doc/README*
@@ -22,8 +24,11 @@
* Fetch and build inputs:
mkdir -p inputs; cd inputs/
wget 'http://miniupnp.free.fr/files/download.php?file=miniupnpc-1.6.tar.gz' -O miniupnpc-1.6.tar.gz
wget 'http://www.openssl.org/source/openssl-1.0.0e.tar.gz'
wget 'http://www.openssl.org/source/openssl-1.0.1b.tar.gz'
wget 'http://download.oracle.com/berkeley-db/db-4.8.30.NC.tar.gz'
wget 'http://zlib.net/zlib-1.2.6.tar.gz'
wget 'ftp://ftp.simplesystems.org/pub/libpng/png/src/libpng-1.5.9.tar.gz'
wget 'http://fukuchi.org/works/qrencode/qrencode-3.2.0.tar.bz2'
wget 'http://downloads.sourceforge.net/project/boost/boost/1.47.0/boost_1_47_0.tar.bz2'
wget 'http://download.qt.nokia.com/qt/source/qt-everywhere-opensource-src-4.7.4.tar.gz'
cd ..
@@ -31,6 +36,8 @@
cp build/out/boost-win32-1.47.0-gitian.zip inputs/
./bin/gbuild ../bitcoin/contrib/gitian-descriptors/qt-win32.yml
cp build/out/qt-win32-4.7.4-gitian.zip inputs/
./bin/gbuild ../bitcoin/contrib/gitian-descriptors/deps-win32.yml
cp build/out/bitcoin-deps-0.0.3.zip inputs/
* Build bitcoind and bitcoin-qt on Linux32, Linux64, and Win32:
./bin/gbuild --commit bitcoin=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian.yml
@@ -65,21 +72,25 @@
rm -rf bitcoin-${VERSION}-win32
* perform Mac build
See this blog post for how Gavin set up his build environment and
patched macdeployqt to build the OSX release:
See this blog post for how Gavin set up his build environment to build the OSX
release; note that a patched version of macdeployqt is not needed anymore, as
the required functionality and fixes are implemented directly in macdeployqtplus:
http://gavintech.blogspot.com/2011/11/deploying-bitcoin-qt-on-osx.html
qmake USE_SSL=1 USE_UPNP=1 bitcoin-qt.pro
Gavin also had trouble with the macports py27-appscript package; he
ended up installing a version that worked with: /usr/bin/easy_install-2.7 appscript
qmake RELEASE=1 USE_UPNP=1 USE_QRCODE=1 bitcoin-qt.pro
make
export QTDIR=/opt/local/share/qt4 # needed to find translations/qt_*.qm files
T=$(contrib/qt_translations.py $QTDIR/translations src/qt/locale)
contrib/macdeploy/macdeployqtplus Bitcoin-Qt.app -add-qt-tr $T -dmg -fancy contrib/macdeploy/fancy.plist
python2.7 contrib/macdeploy/macdeployqtplus Bitcoin-Qt.app -add-qt-tr $T -dmg -fancy contrib/macdeploy/fancy.plist
Build output expected:
Bitcoin-Qt.dmg
* upload source and builds to SourceForge
* upload builds to SourceForge
* create SHA1SUMS for builds, and PGP-sign it
* create SHA256SUMS for builds, and PGP-sign it
* update bitcoin.org version

View File

@@ -1,7 +1,7 @@
Translations
============
The QT GUI can be easily be translated into other languages. Here's how we
The Qt GUI can be easily translated into other languages. Here's how we
handle those translations.
Files and Folders
@@ -30,10 +30,14 @@ This directory contains all translations. Filenames must adhere to this format:
#### Source file
`src/qt/locale/bitcoin_en.ts` is a treated in a special way. It is used as the
source for all other translations. Whenever a string in the code is change
`src/qt/locale/bitcoin_en.ts` is treated in a special way. It is used as the
source for all other translations. Whenever a string in the code is changed
this file must be updated to reflect those changes. Usually, this can be
accomplished by running `lupdate`
accomplished by running `lupdate` (included in the Qt SDK).
An updated source file should be merged to github and transifex will pick it
up from there. Afterwards the new strings show up as "Remaining" in transifex
and can be translated.
Syncing with transifex
----------------------
@@ -42,9 +46,9 @@ We are using http://transifex.net as a frontend for translating the client.
https://www.transifex.net/projects/p/bitcoin/resource/tx/
The "transifex client":http://help.transifex.net/features/client/index.html
will help with fetching new translations from transifex.
The "transifex client" (see: http://help.transifex.net/features/client/)
will help with fetching new translations from transifex. Use the following
config to be able to connect with the client.
### .tx/config
@@ -55,9 +59,22 @@ will help with fetching new translations from transifex.
file_filter = src/qt/locale/bitcoin_<lang>.ts
source_file = src/qt/locale/bitcoin_en.ts
source_lang = en
### .tx/config (for Windows)
[main]
host = https://www.transifex.net
[bitcoin.tx]
file_filter = src\qt\locale\bitcoin_<lang>.ts
source_file = src\qt\locale\bitcoin_en.ts
source_lang = en
It is also possible to directly download new translations one by one from transifex.
### Fetching new translations
1. `tx pull -a`
2. update `src/qt/bitcoin.qrc`
2. update `src/qt/bitcoin.qrc` manually or via
`ls src/qt/locale/*ts|xargs -n1 basename|sed 's/\(bitcoin_\(.*\)\).ts/<file alias="\2">locale/\1.qm<\/file>/'`
3. `git add` new translations from `src/qt/locale/`

35
share/genbuild.sh Executable file
View File

@@ -0,0 +1,35 @@
#!/bin/sh
if [ $# -gt 0 ]; then
FILE="$1"
shift
if [ -f "$FILE" ]; then
INFO="$(head -n 1 "$FILE")"
fi
else
echo "Usage: $0 <filename>"
exit 1
fi
if [ -e "$(which git)" ]; then
# clean 'dirty' status of touched files that haven't been modified
git diff >/dev/null 2>/dev/null
# get a string like "v0.6.0-66-g59887e8-dirty"
DESC="$(git describe --dirty 2>/dev/null)"
# get a string like "2012-04-10 16:27:19 +0200"
TIME="$(git log -n 1 --format="%ci")"
fi
if [ -n "$DESC" ]; then
NEWINFO="#define BUILD_DESC \"$DESC\""
else
NEWINFO="// No build information available"
fi
# only update build.h if necessary
if [ "$INFO" != "$NEWINFO" ]; then
echo "$NEWINFO" >"$FILE"
echo "#define BUILD_DATE \"$TIME\"" >>"$FILE"
fi

View File

@@ -4,6 +4,7 @@ Extract _("...") strings for translation and convert to Qt4 stringdefs so that
they can be picked up by Qt linguist.
'''
from subprocess import Popen, PIPE
import glob
OUT_CPP="src/qt/bitcoinstrings.cpp"
EMPTY=['""']
@@ -44,7 +45,7 @@ def parse_po(text):
return messages
files = ['src/base58.h', 'src/bignum.h', 'src/db.cpp', 'src/db.h', 'src/headers.h', 'src/init.cpp', 'src/init.h', 'src/irc.cpp', 'src/irc.h', 'src/key.h', 'src/main.cpp', 'src/main.h', 'src/net.cpp', 'src/net.h', 'src/noui.h', 'src/script.cpp', 'src/script.h', 'src/serialize.h', 'src/strlcpy.h', 'src/uint256.h', 'src/util.cpp', 'src/util.h']
files = glob.glob('src/*.cpp') + glob.glob('src/*.h')
# xgettext -n --keyword=_ $FILES
child = Popen(['xgettext','--output=-','-n','--keyword=_'] + files, stdout=PIPE)
@@ -53,9 +54,15 @@ child = Popen(['xgettext','--output=-','-n','--keyword=_'] + files, stdout=PIPE)
messages = parse_po(out)
f = open(OUT_CPP, 'w')
f.write('#include <QtGlobal>\n')
f.write('// Automatically generated by extract_strings.py\n')
f.write('static const char *bitcoin_strings[] = {')
f.write("""#include <QtGlobal>
// Automatically generated by extract_strings.py
#ifdef __GNUC__
#define UNUSED __attribute__((unused))
#else
#define UNUSED
#endif
""")
f.write('static const char UNUSED *bitcoin_strings[] = {')
for (msgid, msgstr) in messages:
if msgid != EMPTY:
f.write('QT_TRANSLATE_NOOP("bitcoin-core", %s),\n' % ('\n'.join(msgid)))

View File

@@ -5,7 +5,7 @@ SetCompressor /SOLID lzma
# General Symbol Definitions
!define REGKEY "SOFTWARE\$(^Name)"
!define VERSION 0.5.1
!define VERSION 0.6.1
!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.5.1-win32-setup.exe
OutFile bitcoin-0.6.1-win32-setup.exe
InstallDir $PROGRAMFILES\Bitcoin
CRCCheck on
XPStyle on
BrandingText " "
ShowInstDetails show
VIProductVersion 0.5.1.0
VIProductVersion 0.6.1.3
VIAddVersionKey ProductName Bitcoin
VIAddVersionKey ProductVersion "${VERSION}"
VIAddVersionKey CompanyName "${COMPANY}"
@@ -75,6 +75,10 @@ Section -Main SEC0000
File /r /x *.exe /x *.o ../src\*.*
SetOutPath $INSTDIR
WriteRegStr HKCU "${REGKEY}\Components" Main 1
# Remove old wxwidgets-based-bitcoin executable and locales:
Delete /REBOOTOK $INSTDIR\bitcoin.exe
RMDir /r /REBOOTOK $INSTDIR\locale
SectionEnd
Section -post SEC0001
@@ -94,6 +98,12 @@ Section -post SEC0001
WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" UninstallString $INSTDIR\uninstall.exe
WriteRegDWORD HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" NoModify 1
WriteRegDWORD HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" NoRepair 1
# bitcoin: URI handling disabled for 0.6.0
# WriteRegStr HKCR "bitcoin" "URL Protocol" ""
# WriteRegStr HKCR "bitcoin" "" "URL:Bitcoin"
# WriteRegStr HKCR "bitcoin\DefaultIcon" "" $INSTDIR\bitcoin-qt.exe
# WriteRegStr HKCR "bitcoin\shell\open\command" "" '"$INSTDIR\bitcoin-qt.exe" "$$1"'
SectionEnd
# Macro for selecting uninstaller sections
@@ -131,6 +141,7 @@ Section -un.post UNSEC0001
DeleteRegValue HKCU "${REGKEY}" Path
DeleteRegKey /IfEmpty HKCU "${REGKEY}\Components"
DeleteRegKey /IfEmpty HKCU "${REGKEY}"
DeleteRegKey HKCR "bitcoin"
RmDir /REBOOTOK $SMPROGRAMS\$StartMenuGroup
RmDir /REBOOTOK $INSTDIR
Push $R0

506
src/addrman.cpp Normal file
View File

@@ -0,0 +1,506 @@
// 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.
#include "addrman.h"
using namespace std;
int CAddrInfo::GetTriedBucket(const std::vector<unsigned char> &nKey) const
{
CDataStream ss1(SER_GETHASH, 0);
std::vector<unsigned char> vchKey = GetKey();
ss1 << nKey << vchKey;
uint64 hash1 = Hash(ss1.begin(), ss1.end()).Get64();
CDataStream ss2(SER_GETHASH, 0);
std::vector<unsigned char> vchGroupKey = GetGroup();
ss2 << nKey << vchGroupKey << (hash1 % ADDRMAN_TRIED_BUCKETS_PER_GROUP);
uint64 hash2 = Hash(ss2.begin(), ss2.end()).Get64();
return hash2 % ADDRMAN_TRIED_BUCKET_COUNT;
}
int CAddrInfo::GetNewBucket(const std::vector<unsigned char> &nKey, const CNetAddr& src) const
{
CDataStream ss1(SER_GETHASH, 0);
std::vector<unsigned char> vchGroupKey = GetGroup();
std::vector<unsigned char> vchSourceGroupKey = src.GetGroup();
ss1 << nKey << vchGroupKey << vchSourceGroupKey;
uint64 hash1 = Hash(ss1.begin(), ss1.end()).Get64();
CDataStream ss2(SER_GETHASH, 0);
ss2 << nKey << vchSourceGroupKey << (hash1 % ADDRMAN_NEW_BUCKETS_PER_SOURCE_GROUP);
uint64 hash2 = Hash(ss2.begin(), ss2.end()).Get64();
return hash2 % ADDRMAN_NEW_BUCKET_COUNT;
}
bool CAddrInfo::IsTerrible(int64 nNow) const
{
if (nLastTry && nLastTry >= nNow-60) // never remove things tried the last minute
return false;
if (nTime > nNow + 10*60) // came in a flying DeLorean
return true;
if (nTime==0 || nNow-nTime > ADDRMAN_HORIZON_DAYS*86400) // not seen in over a month
return true;
if (nLastSuccess==0 && nAttempts>=ADDRMAN_RETRIES) // tried three times and never a success
return true;
if (nNow-nLastSuccess > ADDRMAN_MIN_FAIL_DAYS*86400 && nAttempts>=ADDRMAN_MAX_FAILURES) // 10 successive failures in the last week
return true;
return false;
}
double CAddrInfo::GetChance(int64 nNow) const
{
double fChance = 1.0;
int64 nSinceLastSeen = nNow - nTime;
int64 nSinceLastTry = nNow - nLastTry;
if (nSinceLastSeen < 0) nSinceLastSeen = 0;
if (nSinceLastTry < 0) nSinceLastTry = 0;
fChance *= 600.0 / (600.0 + nSinceLastSeen);
// deprioritize very recent attempts away
if (nSinceLastTry < 60*10)
fChance *= 0.01;
// deprioritize 50% after each failed attempt
for (int n=0; n<nAttempts; n++)
fChance /= 1.5;
return fChance;
}
CAddrInfo* CAddrMan::Find(const CNetAddr& addr, int *pnId)
{
std::map<CNetAddr, int>::iterator it = mapAddr.find(addr);
if (it == mapAddr.end())
return NULL;
if (pnId)
*pnId = (*it).second;
std::map<int, CAddrInfo>::iterator it2 = mapInfo.find((*it).second);
if (it2 != mapInfo.end())
return &(*it2).second;
return NULL;
}
CAddrInfo* CAddrMan::Create(const CAddress &addr, const CNetAddr &addrSource, int *pnId)
{
int nId = nIdCount++;
mapInfo[nId] = CAddrInfo(addr, addrSource);
mapAddr[addr] = nId;
mapInfo[nId].nRandomPos = vRandom.size();
vRandom.push_back(nId);
if (pnId)
*pnId = nId;
return &mapInfo[nId];
}
void CAddrMan::SwapRandom(int nRndPos1, int nRndPos2)
{
if (nRndPos1 == nRndPos2)
return;
int nId1 = vRandom[nRndPos1];
int nId2 = vRandom[nRndPos2];
mapInfo[nId1].nRandomPos = nRndPos2;
mapInfo[nId2].nRandomPos = nRndPos1;
vRandom[nRndPos1] = nId2;
vRandom[nRndPos2] = nId1;
}
int CAddrMan::SelectTried(int nKBucket)
{
std::vector<int> &vTried = vvTried[nKBucket];
// random shuffle the first few elements (using the entire list)
// find the least recently tried among them
int64 nOldest = -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)
nOldest = nTemp;
}
return nOldest;
}
int CAddrMan::ShrinkNew(int nUBucket)
{
std::set<int> &vNew = vvNew[nUBucket];
// first look for deletable items
for (std::set<int>::iterator it = vNew.begin(); it != vNew.end(); it++)
{
CAddrInfo &info = mapInfo[*it];
if (info.IsTerrible())
{
if (--info.nRefCount == 0)
{
SwapRandom(info.nRandomPos, vRandom.size()-1);
vRandom.pop_back();
mapAddr.erase(info);
mapInfo.erase(*it);
nNew--;
}
vNew.erase(it);
return 0;
}
}
// otherwise, select four randomly, and pick the oldest of those to replace
int n[4] = {GetRandInt(vNew.size()), GetRandInt(vNew.size()), GetRandInt(vNew.size()), GetRandInt(vNew.size())};
int nI = 0;
int nOldest = -1;
for (std::set<int>::iterator it = vNew.begin(); it != vNew.end(); it++)
{
if (nI == n[0] || nI == n[1] || nI == n[2] || nI == n[3])
{
if (nOldest == -1 || mapInfo[*it].nTime < mapInfo[nOldest].nTime)
nOldest = *it;
}
nI++;
}
CAddrInfo &info = mapInfo[nOldest];
if (--info.nRefCount == 0)
{
SwapRandom(info.nRandomPos, vRandom.size()-1);
vRandom.pop_back();
mapAddr.erase(info);
mapInfo.erase(nOldest);
nNew--;
}
vNew.erase(nOldest);
return 1;
}
void CAddrMan::MakeTried(CAddrInfo& info, int nId, int nOrigin)
{
// remove the entry from all new buckets
for (std::vector<std::set<int> >::iterator it = vvNew.begin(); it != vvNew.end(); it++)
{
if ((*it).erase(nId))
info.nRefCount--;
}
nNew--;
// what tried bucket to move the entry to
int nKBucket = info.GetTriedBucket(nKey);
std::vector<int> &vTried = vvTried[nKBucket];
// first check whether there is place to just add it
if (vTried.size() < ADDRMAN_TRIED_BUCKET_SIZE)
{
vTried.push_back(nId);
nTried++;
info.fInTried = true;
return;
}
// otherwise, find an item to evict
int nPos = SelectTried(nKBucket);
// find which new bucket it belongs to
int nUBucket = mapInfo[vTried[nPos]].GetNewBucket(nKey);
std::set<int> &vNew = vvNew[nUBucket];
// remove the to-be-replaced tried entry from the tried set
CAddrInfo& infoOld = mapInfo[vTried[nPos]];
infoOld.fInTried = false;
infoOld.nRefCount = 1;
// do not update nTried, as we are going to move something else there immediately
// check whether there is place in that one,
if (vNew.size() < ADDRMAN_NEW_BUCKET_SIZE)
{
// if so, move it back there
vNew.insert(vTried[nPos]);
} else {
// otherwise, move it to the new bucket nId came from (there is certainly place there)
vvNew[nOrigin].insert(vTried[nPos]);
}
nNew++;
vTried[nPos] = nId;
// we just overwrote an entry in vTried; no need to update nTried
info.fInTried = true;
return;
}
void CAddrMan::Good_(const CService &addr, int64 nTime)
{
// printf("Good: addr=%s\n", addr.ToString().c_str());
int nId;
CAddrInfo *pinfo = Find(addr, &nId);
// if not found, bail out
if (!pinfo)
return;
CAddrInfo &info = *pinfo;
// check whether we are talking about the exact same CService (including same port)
if (info != addr)
return;
// update info
info.nLastSuccess = nTime;
info.nLastTry = nTime;
info.nTime = nTime;
info.nAttempts = 0;
// if it is already in the tried set, don't do anything else
if (info.fInTried)
return;
// find a bucket it is in now
int nRnd = GetRandInt(vvNew.size());
int nUBucket = -1;
for (unsigned int n = 0; n < vvNew.size(); n++)
{
int nB = (n+nRnd) % vvNew.size();
std::set<int> &vNew = vvNew[nB];
if (vNew.count(nId))
{
nUBucket = nB;
break;
}
}
// if no bucket is found, something bad happened;
// TODO: maybe re-add the node, but for now, just bail out
if (nUBucket == -1) return;
printf("Moving %s to tried\n", addr.ToString().c_str());
// move nId to the tried tables
MakeTried(info, nId, nUBucket);
}
bool CAddrMan::Add_(const CAddress &addr, const CNetAddr& source, int64 nTimePenalty)
{
if (!addr.IsRoutable())
return false;
bool fNew = false;
int nId;
CAddrInfo *pinfo = Find(addr, &nId);
if (pinfo)
{
// periodically update nTime
bool fCurrentlyOnline = (GetAdjustedTime() - addr.nTime < 24 * 60 * 60);
int64 nUpdateInterval = (fCurrentlyOnline ? 60 * 60 : 24 * 60 * 60);
if (addr.nTime && (!pinfo->nTime || pinfo->nTime < addr.nTime - nUpdateInterval - nTimePenalty))
pinfo->nTime = max((int64)0, addr.nTime - nTimePenalty);
// add services
pinfo->nServices |= addr.nServices;
// do not update if no new information is present
if (!addr.nTime || (pinfo->nTime && addr.nTime <= pinfo->nTime))
return false;
// do not update if the entry was already in the "tried" table
if (pinfo->fInTried)
return false;
// do not update if the max reference count is reached
if (pinfo->nRefCount == ADDRMAN_NEW_BUCKETS_PER_ADDRESS)
return false;
// stochastic test: previous nRefCount == N: 2^N times harder to increase it
int nFactor = 1;
for (int n=0; n<pinfo->nRefCount; n++)
nFactor *= 2;
if (nFactor > 1 && (GetRandInt(nFactor) != 0))
return false;
} else {
pinfo = Create(addr, source, &nId);
pinfo->nTime = max((int64)0, (int64)pinfo->nTime - nTimePenalty);
// printf("Added %s [nTime=%fhr]\n", pinfo->ToString().c_str(), (GetAdjustedTime() - pinfo->nTime) / 3600.0);
nNew++;
fNew = true;
}
int nUBucket = pinfo->GetNewBucket(nKey, source);
std::set<int> &vNew = vvNew[nUBucket];
if (!vNew.count(nId))
{
pinfo->nRefCount++;
if (vNew.size() == ADDRMAN_NEW_BUCKET_SIZE)
ShrinkNew(nUBucket);
vvNew[nUBucket].insert(nId);
}
return fNew;
}
void CAddrMan::Attempt_(const CService &addr, int64 nTime)
{
CAddrInfo *pinfo = Find(addr);
// if not found, bail out
if (!pinfo)
return;
CAddrInfo &info = *pinfo;
// check whether we are talking about the exact same CService (including same port)
if (info != addr)
return;
// update info
info.nLastTry = nTime;
info.nAttempts++;
}
CAddress CAddrMan::Select_(int nUnkBias)
{
if (size() == 0)
return CAddress();
double nCorTried = sqrt(nTried) * (100.0 - nUnkBias);
double nCorNew = sqrt(nNew) * nUnkBias;
if ((nCorTried + nCorNew)*GetRandInt(1<<30)/(1<<30) < nCorTried)
{
// use a tried node
double fChanceFactor = 1.0;
while(1)
{
int nKBucket = GetRandInt(vvTried.size());
std::vector<int> &vTried = vvTried[nKBucket];
if (vTried.size() == 0) continue;
int nPos = GetRandInt(vTried.size());
CAddrInfo &info = mapInfo[vTried[nPos]];
if (GetRandInt(1<<30) < fChanceFactor*info.GetChance()*(1<<30))
return info;
fChanceFactor *= 1.2;
}
} else {
// use an new node
double fChanceFactor = 1.0;
while(1)
{
int nUBucket = GetRandInt(vvNew.size());
std::set<int> &vNew = vvNew[nUBucket];
if (vNew.size() == 0) continue;
int nPos = GetRandInt(vNew.size());
std::set<int>::iterator it = vNew.begin();
while (nPos--)
it++;
CAddrInfo &info = mapInfo[*it];
if (GetRandInt(1<<30) < fChanceFactor*info.GetChance()*(1<<30))
return info;
fChanceFactor *= 1.2;
}
}
}
#ifdef DEBUG_ADDRMAN
int CAddrMan::Check_()
{
std::set<int> setTried;
std::map<int, int> mapNew;
if (vRandom.size() != nTried + nNew) return -7;
for (std::map<int, CAddrInfo>::iterator it = mapInfo.begin(); it != mapInfo.end(); it++)
{
int n = (*it).first;
CAddrInfo &info = (*it).second;
if (info.fInTried)
{
if (!info.nLastSuccess) return -1;
if (info.nRefCount) return -2;
setTried.insert(n);
} else {
if (info.nRefCount < 0 || info.nRefCount > ADDRMAN_NEW_BUCKETS_PER_ADDRESS) return -3;
if (!info.nRefCount) return -4;
mapNew[n] = info.nRefCount;
}
if (mapAddr[info] != n) return -5;
if (info.nRandomPos<0 || info.nRandomPos>=vRandom.size() || vRandom[info.nRandomPos] != n) return -14;
if (info.nLastTry < 0) return -6;
if (info.nLastSuccess < 0) return -8;
}
if (setTried.size() != nTried) return -9;
if (mapNew.size() != nNew) return -10;
for (int n=0; n<vvTried.size(); n++)
{
std::vector<int> &vTried = vvTried[n];
for (std::vector<int>::iterator it = vTried.begin(); it != vTried.end(); it++)
{
if (!setTried.count(*it)) return -11;
setTried.erase(*it);
}
}
for (int n=0; n<vvNew.size(); n++)
{
std::set<int> &vNew = vvNew[n];
for (std::set<int>::iterator it = vNew.begin(); it != vNew.end(); it++)
{
if (!mapNew.count(*it)) return -12;
if (--mapNew[*it] == 0)
mapNew.erase(*it);
}
}
if (setTried.size()) return -13;
if (mapNew.size()) return -15;
return 0;
}
#endif
void CAddrMan::GetAddr_(std::vector<CAddress> &vAddr)
{
int nNodes = ADDRMAN_GETADDR_MAX_PCT*vRandom.size()/100;
if (nNodes > ADDRMAN_GETADDR_MAX)
nNodes = ADDRMAN_GETADDR_MAX;
// perform a random shuffle over the first nNodes elements of vRandom (selecting from all)
for (int n = 0; n<nNodes; n++)
{
int nRndPos = GetRandInt(vRandom.size() - n) + n;
SwapRandom(n, nRndPos);
vAddr.push_back(mapInfo[vRandom[n]]);
}
}
void CAddrMan::Connected_(const CService &addr, int64 nTime)
{
CAddrInfo *pinfo = Find(addr);
// if not found, bail out
if (!pinfo)
return;
CAddrInfo &info = *pinfo;
// check whether we are talking about the exact same CService (including same port)
if (info != addr)
return;
// update info
int64 nUpdateInterval = 20 * 60;
if (nTime - info.nTime > nUpdateInterval)
info.nTime = nTime;
}

502
src/addrman.h Normal file
View File

@@ -0,0 +1,502 @@
// 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.
#ifndef _BITCOIN_ADDRMAN
#define _BITCOIN_ADDRMAN 1
#include "netbase.h"
#include "protocol.h"
#include "util.h"
#include <map>
#include <vector>
#include <openssl/rand.h>
/** Extended statistics about a CAddress */
class CAddrInfo : public CAddress
{
private:
// where knowledge about this address first came from
CNetAddr source;
// last succesfull connection by us
int64 nLastSuccess;
// last try whatsoever by us:
// int64 CAddress::nLastTry
// connection attempts since last succesful attempt
int nAttempts;
// reference count in new sets (memory only)
int nRefCount;
// in tried set? (memory only)
bool fInTried;
// position in vRandom
int nRandomPos;
friend class CAddrMan;
public:
IMPLEMENT_SERIALIZE(
CAddress* pthis = (CAddress*)(this);
READWRITE(*pthis);
READWRITE(source);
READWRITE(nLastSuccess);
READWRITE(nAttempts);
)
void Init()
{
nLastSuccess = 0;
nLastTry = 0;
nAttempts = 0;
nRefCount = 0;
fInTried = false;
nRandomPos = -1;
}
CAddrInfo(const CAddress &addrIn, const CNetAddr &addrSource) : CAddress(addrIn)
{
Init();
}
CAddrInfo() : CAddress(), source()
{
Init();
}
// Calculate in which "tried" bucket this entry belongs
int GetTriedBucket(const std::vector<unsigned char> &nKey) const;
// Calculate in which "new" bucket this entry belongs, given a certain source
int GetNewBucket(const std::vector<unsigned char> &nKey, const CNetAddr& src) const;
// Calculate in which "new" bucket this entry belongs, using its default source
int GetNewBucket(const std::vector<unsigned char> &nKey) const
{
return GetNewBucket(nKey, source);
}
// Determine whether the statistics about this entry are bad enough so that it can just be deleted
bool IsTerrible(int64 nNow = GetAdjustedTime()) const;
// Calculate the relative chance this entry should be given when selecting nodes to connect to
double GetChance(int64 nNow = GetAdjustedTime()) const;
};
// Stochastic address manager
//
// Design goals:
// * Only keep a limited number of addresses around, so that addr.dat and memory requirements do not grow without bound.
// * Keep the address tables in-memory, and asynchronously dump the entire to able in addr.dat.
// * Make sure no (localized) attacker can fill the entire table with his nodes/addresses.
//
// To that end:
// * Addresses are organized into buckets.
// * Address that have not yet been tried go into 256 "new" buckets.
// * Based on the address range (/16 for IPv4) of source of the information, 32 buckets are selected at random
// * The actual bucket is chosen from one of these, based on the range the address itself is located.
// * One single address can occur in up to 4 different buckets, to increase selection chances for addresses that
// are seen frequently. The chance for increasing this multiplicity decreases exponentially.
// * When adding a new address to a full bucket, a randomly chosen entry (with a bias favoring less recently seen
// ones) is removed from it first.
// * Addresses of nodes that are known to be accessible go into 64 "tried" buckets.
// * Each address range selects at random 4 of these buckets.
// * The actual bucket is chosen from one of these, based on the full address.
// * When adding a new good address to a full bucket, a randomly chosen entry (with a bias favoring less recently
// tried ones) is evicted from it, back to the "new" buckets.
// * Bucket selection is based on cryptographic hashing, using a randomly-generated 256-bit key, which should not
// be observable by adversaries.
// * Several indexes are kept for high performance. Defining DEBUG_ADDRMAN will introduce frequent (and expensive)
// consistency checks for the entire datastructure.
// total number of buckets for tried addresses
#define ADDRMAN_TRIED_BUCKET_COUNT 64
// maximum allowed number of entries in buckets for tried addresses
#define ADDRMAN_TRIED_BUCKET_SIZE 64
// total number of buckets for new addresses
#define ADDRMAN_NEW_BUCKET_COUNT 256
// maximum allowed number of entries in buckets for new addresses
#define ADDRMAN_NEW_BUCKET_SIZE 64
// over how many buckets entries with tried addresses from a single group (/16 for IPv4) are spread
#define ADDRMAN_TRIED_BUCKETS_PER_GROUP 4
// over how many buckets entries with new addresses originating from a single group are spread
#define ADDRMAN_NEW_BUCKETS_PER_SOURCE_GROUP 32
// in how many buckets for entries with new addresses a single address may occur
#define ADDRMAN_NEW_BUCKETS_PER_ADDRESS 4
// how many entries in a bucket with tried addresses are inspected, when selecting one to replace
#define ADDRMAN_TRIED_ENTRIES_INSPECT_ON_EVICT 4
// how old addresses can maximally be
#define ADDRMAN_HORIZON_DAYS 30
// after how many failed attempts we give up on a new node
#define ADDRMAN_RETRIES 3
// how many successive failures are allowed ...
#define ADDRMAN_MAX_FAILURES 10
// ... in at least this many days
#define ADDRMAN_MIN_FAIL_DAYS 7
// the maximum percentage of nodes to return in a getaddr call
#define ADDRMAN_GETADDR_MAX_PCT 23
// the maximum number of nodes to return in a getaddr call
#define ADDRMAN_GETADDR_MAX 2500
/** Stochastical (IP) address manager */
class CAddrMan
{
private:
// critical section to protect the inner data structures
mutable CCriticalSection cs;
// secret key to randomize bucket select with
std::vector<unsigned char> nKey;
// last used nId
int nIdCount;
// table with information about all nId's
std::map<int, CAddrInfo> mapInfo;
// find an nId based on its network address
std::map<CNetAddr, int> mapAddr;
// randomly-ordered vector of all nId's
std::vector<int> vRandom;
// number of "tried" entries
int nTried;
// list of "tried" buckets
std::vector<std::vector<int> > vvTried;
// number of (unique) "new" entries
int nNew;
// list of "new" buckets
std::vector<std::set<int> > vvNew;
protected:
// Find an entry.
CAddrInfo* Find(const CNetAddr& addr, int *pnId = NULL);
// find an entry, creating it if necessary.
// nTime and nServices of found node is updated, if necessary.
CAddrInfo* Create(const CAddress &addr, const CNetAddr &addrSource, int *pnId = NULL);
// Swap two elements in vRandom.
void SwapRandom(int nRandomPos1, int nRandomPos2);
// Return position in given bucket to replace.
int SelectTried(int nKBucket);
// Remove an element from a "new" bucket.
// This is the only place where actual deletes occur.
// They are never deleted while in the "tried" table, only possibly evicted back to the "new" table.
int ShrinkNew(int nUBucket);
// Move an entry from the "new" table(s) to the "tried" table
// @pre vvUnkown[nOrigin].count(nId) != 0
void MakeTried(CAddrInfo& info, int nId, int nOrigin);
// Mark an entry "good", possibly moving it from "new" to "tried".
void Good_(const CService &addr, int64 nTime);
// Add an entry to the "new" table.
bool Add_(const CAddress &addr, const CNetAddr& source, int64 nTimePenalty);
// Mark an entry as attempted to connect.
void Attempt_(const CService &addr, int64 nTime);
// Select an address to connect to.
// nUnkBias determines how much to favor new addresses over tried ones (min=0, max=100)
CAddress Select_(int nUnkBias);
#ifdef DEBUG_ADDRMAN
// Perform consistency check. Returns an error code or zero.
int Check_();
#endif
// Select several addresses at once.
void GetAddr_(std::vector<CAddress> &vAddr);
// Mark an entry as currently-connected-to.
void Connected_(const CService &addr, int64 nTime);
public:
IMPLEMENT_SERIALIZE
(({
// serialized format:
// * version byte (currently 0)
// * nKey
// * nNew
// * nTried
// * number of "new" buckets
// * all nNew addrinfo's in vvNew
// * all nTried addrinfo's in vvTried
// * for each bucket:
// * number of elements
// * for each element: index
//
// Notice that vvTried, mapAddr and vVector are never encoded explicitly;
// they are instead reconstructed from the other information.
//
// vvNew is serialized, but only used if ADDRMAN_UNKOWN_BUCKET_COUNT didn't change,
// otherwise it is reconstructed as well.
//
// This format is more complex, but significantly smaller (at most 1.5 MiB), and supports
// changes to the ADDRMAN_ parameters without breaking the on-disk structure.
{
LOCK(cs);
unsigned char nVersion = 0;
READWRITE(nVersion);
READWRITE(nKey);
READWRITE(nNew);
READWRITE(nTried);
CAddrMan *am = const_cast<CAddrMan*>(this);
if (fWrite)
{
int nUBuckets = ADDRMAN_NEW_BUCKET_COUNT;
READWRITE(nUBuckets);
std::map<int, int> mapUnkIds;
int nIds = 0;
for (std::map<int, CAddrInfo>::iterator it = am->mapInfo.begin(); it != am->mapInfo.end(); it++)
{
if (nIds == nNew) break; // this means nNew was wrong, oh ow
mapUnkIds[(*it).first] = nIds;
CAddrInfo &info = (*it).second;
if (info.nRefCount)
{
READWRITE(info);
nIds++;
}
}
nIds = 0;
for (std::map<int, CAddrInfo>::iterator it = am->mapInfo.begin(); it != am->mapInfo.end(); it++)
{
if (nIds == nTried) break; // this means nTried was wrong, oh ow
CAddrInfo &info = (*it).second;
if (info.fInTried)
{
READWRITE(info);
nIds++;
}
}
for (std::vector<std::set<int> >::iterator it = am->vvNew.begin(); it != am->vvNew.end(); it++)
{
const std::set<int> &vNew = (*it);
int nSize = vNew.size();
READWRITE(nSize);
for (std::set<int>::iterator it2 = vNew.begin(); it2 != vNew.end(); it2++)
{
int nIndex = mapUnkIds[*it2];
READWRITE(nIndex);
}
}
} else {
int nUBuckets = 0;
READWRITE(nUBuckets);
am->nIdCount = 0;
am->mapInfo.clear();
am->mapAddr.clear();
am->vRandom.clear();
am->vvTried = std::vector<std::vector<int> >(ADDRMAN_TRIED_BUCKET_COUNT, std::vector<int>(0));
am->vvNew = std::vector<std::set<int> >(ADDRMAN_NEW_BUCKET_COUNT, std::set<int>());
for (int n = 0; n < am->nNew; n++)
{
CAddrInfo &info = am->mapInfo[n];
READWRITE(info);
am->mapAddr[info] = n;
info.nRandomPos = vRandom.size();
am->vRandom.push_back(n);
if (nUBuckets != ADDRMAN_NEW_BUCKET_COUNT)
{
am->vvNew[info.GetNewBucket(am->nKey)].insert(n);
info.nRefCount++;
}
}
am->nIdCount = am->nNew;
int nLost = 0;
for (int n = 0; n < am->nTried; n++)
{
CAddrInfo info;
READWRITE(info);
std::vector<int> &vTried = am->vvTried[info.GetTriedBucket(am->nKey)];
if (vTried.size() < ADDRMAN_TRIED_BUCKET_SIZE)
{
info.nRandomPos = vRandom.size();
info.fInTried = true;
am->vRandom.push_back(am->nIdCount);
am->mapInfo[am->nIdCount] = info;
am->mapAddr[info] = am->nIdCount;
vTried.push_back(am->nIdCount);
am->nIdCount++;
} else {
nLost++;
}
}
am->nTried -= nLost;
for (int b = 0; b < nUBuckets; b++)
{
std::set<int> &vNew = am->vvNew[b];
int nSize = 0;
READWRITE(nSize);
for (int n = 0; n < nSize; n++)
{
int nIndex = 0;
READWRITE(nIndex);
CAddrInfo &info = am->mapInfo[nIndex];
if (nUBuckets == ADDRMAN_NEW_BUCKET_COUNT && info.nRefCount < ADDRMAN_NEW_BUCKETS_PER_ADDRESS)
{
info.nRefCount++;
vNew.insert(nIndex);
}
}
}
}
}
});)
CAddrMan() : vRandom(0), vvTried(ADDRMAN_TRIED_BUCKET_COUNT, std::vector<int>(0)), vvNew(ADDRMAN_NEW_BUCKET_COUNT, std::set<int>())
{
nKey.resize(32);
RAND_bytes(&nKey[0], 32);
nIdCount = 0;
nTried = 0;
nNew = 0;
}
// Return the number of (unique) addresses in all tables.
int size()
{
return vRandom.size();
}
// Consistency check
void Check()
{
#ifdef DEBUG_ADDRMAN
{
LOCK(cs);
int err;
if ((err=Check_()))
printf("ADDRMAN CONSISTENCY CHECK FAILED!!! err=%i\n", err);
}
#endif
}
// Add a single address.
bool Add(const CAddress &addr, const CNetAddr& source, int64 nTimePenalty = 0)
{
bool fRet = false;
{
LOCK(cs);
Check();
fRet |= Add_(addr, source, nTimePenalty);
Check();
}
if (fRet)
printf("Added %s from %s: %i tried, %i new\n", addr.ToStringIPPort().c_str(), source.ToString().c_str(), nTried, nNew);
return fRet;
}
// Add multiple addresses.
bool Add(const std::vector<CAddress> &vAddr, const CNetAddr& source, int64 nTimePenalty = 0)
{
int nAdd = 0;
{
LOCK(cs);
Check();
for (std::vector<CAddress>::const_iterator it = vAddr.begin(); it != vAddr.end(); it++)
nAdd += Add_(*it, source, nTimePenalty) ? 1 : 0;
Check();
}
if (nAdd)
printf("Added %i addresses from %s: %i tried, %i new\n", nAdd, source.ToString().c_str(), nTried, nNew);
return nAdd > 0;
}
// Mark an entry as accessible.
void Good(const CService &addr, int64 nTime = GetAdjustedTime())
{
{
LOCK(cs);
Check();
Good_(addr, nTime);
Check();
}
}
// Mark an entry as connection attempted to.
void Attempt(const CService &addr, int64 nTime = GetAdjustedTime())
{
{
LOCK(cs);
Check();
Attempt_(addr, nTime);
Check();
}
}
// Choose an address to connect to.
// nUnkBias determines how much "new" entries are favored over "tried" ones (0-100).
CAddress Select(int nUnkBias = 50)
{
CAddress addrRet;
{
LOCK(cs);
Check();
addrRet = Select_(nUnkBias);
Check();
}
return addrRet;
}
// Return a bunch of addresses, selected at random.
std::vector<CAddress> GetAddr()
{
Check();
std::vector<CAddress> vAddr;
{
LOCK(cs);
GetAddr_(vAddr);
}
Check();
return vAddr;
}
// Mark an entry as currently-connected-to.
void Connected(const CService &addr, int64 nTime = GetAdjustedTime())
{
{
LOCK(cs);
Check();
Connected_(addr, nTime);
Check();
}
}
};
#endif

123
src/allocators.h Normal file
View File

@@ -0,0 +1,123 @@
// 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.
#ifndef BITCOIN_ALLOCATORS_H
#define BITCOIN_ALLOCATORS_H
#include <string.h>
#include <string>
#ifdef WIN32
#ifdef _WIN32_WINNT
#undef _WIN32_WINNT
#endif
#define _WIN32_WINNT 0x0501
#define WIN32_LEAN_AND_MEAN 1
#ifndef NOMINMAX
#define NOMINMAX
#endif
#include <windows.h>
// This is used to attempt to keep keying material out of swap
// Note that VirtualLock does not provide this as a guarantee on Windows,
// but, in practice, memory that has been VirtualLock'd almost never gets written to
// the pagefile except in rare circumstances where memory is extremely low.
#define mlock(p, n) VirtualLock((p), (n));
#define munlock(p, n) VirtualUnlock((p), (n));
#else
#include <sys/mman.h>
#include <limits.h>
/* This comes from limits.h if it's not defined there set a sane default */
#ifndef PAGESIZE
#include <unistd.h>
#define PAGESIZE sysconf(_SC_PAGESIZE)
#endif
#define mlock(a,b) \
mlock(((void *)(((size_t)(a)) & (~((PAGESIZE)-1)))),\
(((((size_t)(a)) + (b) - 1) | ((PAGESIZE) - 1)) + 1) - (((size_t)(a)) & (~((PAGESIZE) - 1))))
#define munlock(a,b) \
munlock(((void *)(((size_t)(a)) & (~((PAGESIZE)-1)))),\
(((((size_t)(a)) + (b) - 1) | ((PAGESIZE) - 1)) + 1) - (((size_t)(a)) & (~((PAGESIZE) - 1))))
#endif
//
// Allocator that locks its contents from being paged
// out of memory and clears its contents before deletion.
//
template<typename T>
struct secure_allocator : public std::allocator<T>
{
// MSVC8 default copy constructor is broken
typedef std::allocator<T> base;
typedef typename base::size_type size_type;
typedef typename base::difference_type difference_type;
typedef typename base::pointer pointer;
typedef typename base::const_pointer const_pointer;
typedef typename base::reference reference;
typedef typename base::const_reference const_reference;
typedef typename base::value_type value_type;
secure_allocator() throw() {}
secure_allocator(const secure_allocator& a) throw() : base(a) {}
template <typename U>
secure_allocator(const secure_allocator<U>& a) throw() : base(a) {}
~secure_allocator() throw() {}
template<typename _Other> struct rebind
{ typedef secure_allocator<_Other> other; };
T* allocate(std::size_t n, const void *hint = 0)
{
T *p;
p = std::allocator<T>::allocate(n, hint);
if (p != NULL)
mlock(p, sizeof(T) * n);
return p;
}
void deallocate(T* p, std::size_t n)
{
if (p != NULL)
{
memset(p, 0, sizeof(T) * n);
munlock(p, sizeof(T) * n);
}
std::allocator<T>::deallocate(p, n);
}
};
//
// Allocator that clears its contents before deletion.
//
template<typename T>
struct zero_after_free_allocator : public std::allocator<T>
{
// MSVC8 default copy constructor is broken
typedef std::allocator<T> base;
typedef typename base::size_type size_type;
typedef typename base::difference_type difference_type;
typedef typename base::pointer pointer;
typedef typename base::const_pointer const_pointer;
typedef typename base::reference reference;
typedef typename base::const_reference const_reference;
typedef typename base::value_type value_type;
zero_after_free_allocator() throw() {}
zero_after_free_allocator(const zero_after_free_allocator& a) throw() : base(a) {}
template <typename U>
zero_after_free_allocator(const zero_after_free_allocator<U>& a) throw() : base(a) {}
~zero_after_free_allocator() throw() {}
template<typename _Other> struct rebind
{ typedef zero_after_free_allocator<_Other> other; };
void deallocate(T* p, std::size_t n)
{
if (p != NULL)
memset(p, 0, sizeof(T) * n);
std::allocator<T>::deallocate(p, n);
}
};
// 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

View File

@@ -1,5 +1,5 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2011 The Bitcoin Developers
// Copyright (c) 2009-2012 The Bitcoin Developers
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
@@ -18,6 +18,7 @@
#include <string>
#include <vector>
#include "bignum.h"
#include "key.h"
static const char* pszBase58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
@@ -168,7 +169,7 @@ inline bool DecodeBase58Check(const std::string& str, std::vector<unsigned char>
// Base class for all base58-encoded data
/** Base class for all base58-encoded data */
class CBase58Data
{
protected:
@@ -251,33 +252,61 @@ public:
bool operator> (const CBase58Data& b58) const { return CompareTo(b58) > 0; }
};
// base58-encoded bitcoin addresses
// Addresses have version 0 or 111 (testnet)
// The data vector contains RIPEMD160(SHA256(pubkey)), where pubkey is the serialized public key
/** base58-encoded bitcoin addresses.
* Public-key-hash-addresses have version 0 (or 111 testnet).
* The data vector contains RIPEMD160(SHA256(pubkey)), where pubkey is the serialized public key.
* Script-hash-addresses have version 5 (or 196 testnet).
* The data vector contains RIPEMD160(SHA256(cscript)), where cscript is the serialized redemption script.
*/
class CBitcoinAddress : public CBase58Data
{
public:
enum
{
PUBKEY_ADDRESS = 0,
SCRIPT_ADDRESS = 5,
PUBKEY_ADDRESS_TEST = 111,
SCRIPT_ADDRESS_TEST = 196,
};
bool SetHash160(const uint160& hash160)
{
SetData(fTestNet ? 111 : 0, &hash160, 20);
SetData(fTestNet ? PUBKEY_ADDRESS_TEST : PUBKEY_ADDRESS, &hash160, 20);
return true;
}
bool SetPubKey(const std::vector<unsigned char>& vchPubKey)
void SetPubKey(const std::vector<unsigned char>& vchPubKey)
{
return SetHash160(Hash160(vchPubKey));
SetHash160(Hash160(vchPubKey));
}
bool SetScriptHash160(const uint160& hash160)
{
SetData(fTestNet ? SCRIPT_ADDRESS_TEST : SCRIPT_ADDRESS, &hash160, 20);
return true;
}
bool IsValid() const
{
int nExpectedSize = 20;
unsigned int nExpectedSize = 20;
bool fExpectTestNet = false;
switch(nVersion)
{
case 0:
case PUBKEY_ADDRESS:
nExpectedSize = 20; // Hash of public key
fExpectTestNet = false;
break;
case SCRIPT_ADDRESS:
nExpectedSize = 20; // Hash of CScript
fExpectTestNet = false;
break;
case 111:
case PUBKEY_ADDRESS_TEST:
nExpectedSize = 20;
fExpectTestNet = true;
break;
case SCRIPT_ADDRESS_TEST:
nExpectedSize = 20;
fExpectTestNet = true;
break;
@@ -286,6 +315,14 @@ public:
}
return fExpectTestNet == fTestNet && vchData.size() == nExpectedSize;
}
bool IsScript() const
{
if (!IsValid())
return false;
if (fTestNet)
return nVersion == SCRIPT_ADDRESS_TEST;
return nVersion == SCRIPT_ADDRESS;
}
CBitcoinAddress()
{
@@ -320,4 +357,63 @@ public:
}
};
/** A base58-encoded secret key */
class CBitcoinSecret : public CBase58Data
{
public:
void SetSecret(const CSecret& vchSecret, bool fCompressed)
{
assert(vchSecret.size() == 32);
SetData(fTestNet ? 239 : 128, &vchSecret[0], vchSecret.size());
if (fCompressed)
vchData.push_back(1);
}
CSecret GetSecret(bool &fCompressedOut)
{
CSecret vchSecret;
vchSecret.resize(32);
memcpy(&vchSecret[0], &vchData[0], 32);
fCompressedOut = vchData.size() == 33;
return vchSecret;
}
bool IsValid() const
{
bool fExpectTestNet = false;
switch(nVersion)
{
case 128:
break;
case 239:
fExpectTestNet = true;
break;
default:
return false;
}
return fExpectTestNet == fTestNet && (vchData.size() == 32 || (vchData.size() == 33 && vchData[32] == 1));
}
bool SetString(const char* pszSecret)
{
return CBase58Data::SetString(pszSecret) && IsValid();
}
bool SetString(const std::string& strSecret)
{
return SetString(strSecret.c_str());
}
CBitcoinSecret(const CSecret& vchSecret, bool fCompressed)
{
SetSecret(vchSecret, fCompressed);
}
CBitcoinSecret()
{
}
};
#endif

View File

@@ -1,5 +1,5 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2011 The Bitcoin developers
// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_BIGNUM_H
@@ -9,8 +9,9 @@
#include <vector>
#include <openssl/bn.h>
#include "util.h"
#include "util.h" // for uint64
/** Errors thrown by the bignum class */
class bignum_error : public std::runtime_error
{
public:
@@ -18,7 +19,7 @@ public:
};
/** RAII encapsulated BN_CTX (OpenSSL bignum context) */
class CAutoBN_CTX
{
protected:
@@ -46,7 +47,7 @@ public:
};
/** C++ wrapper for BIGNUM (OpenSSL bignum) */
class CBigNum : public BIGNUM
{
public:
@@ -77,7 +78,8 @@ public:
BN_clear_free(this);
}
CBigNum(char n) { BN_init(this); if (n >= 0) setulong(n); else setint64(n); }
//CBigNum(char n) is not portable. Use 'signed char' or 'unsigned char'.
CBigNum(signed char n) { BN_init(this); if (n >= 0) setulong(n); else setint64(n); }
CBigNum(short n) { BN_init(this); if (n >= 0) setulong(n); else setint64(n); }
CBigNum(int n) { BN_init(this); if (n >= 0) setulong(n); else setint64(n); }
CBigNum(long n) { BN_init(this); if (n >= 0) setulong(n); else setint64(n); }
@@ -115,9 +117,9 @@ public:
{
unsigned long n = BN_get_word(this);
if (!BN_is_negative(this))
return (n > INT_MAX ? INT_MAX : n);
return (n > (unsigned long)std::numeric_limits<int>::max() ? std::numeric_limits<int>::max() : n);
else
return (n > INT_MAX ? INT_MIN : -(int)n);
return (n > (unsigned long)std::numeric_limits<int>::max() ? std::numeric_limits<int>::min() : -(int)n);
}
void setint64(int64 n)
@@ -220,7 +222,7 @@ public:
if (vch.size() > 4)
vch[4] &= 0x7f;
uint256 n = 0;
for (int i = 0, j = vch.size()-1; i < sizeof(n) && j >= 4; i++, j--)
for (unsigned int i = 0, j = vch.size()-1; i < sizeof(n) && j >= 4; i++, j--)
((unsigned char*)&n)[i] = vch[j];
return n;
}
@@ -243,7 +245,7 @@ public:
std::vector<unsigned char> getvch() const
{
unsigned int nSize = BN_bn2mpi(this, NULL);
if (nSize < 4)
if (nSize <= 4)
return std::vector<unsigned char>();
std::vector<unsigned char> vch(nSize);
BN_bn2mpi(this, &vch[0]);
@@ -295,12 +297,12 @@ public:
psz++;
// hex string to bignum
static char phexdigit[256] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0 };
static signed char phexdigit[256] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0 };
*this = 0;
while (isxdigit(*psz))
{
*this <<= 4;
int n = phexdigit[*psz++];
int n = phexdigit[(unsigned char)*psz++];
*this += n;
}
if (fNegative)
@@ -338,19 +340,19 @@ public:
return ToString(16);
}
unsigned int GetSerializeSize(int nType=0, int nVersion=VERSION) const
unsigned int GetSerializeSize(int nType=0, int nVersion=PROTOCOL_VERSION) const
{
return ::GetSerializeSize(getvch(), nType, nVersion);
}
template<typename Stream>
void Serialize(Stream& s, int nType=0, int nVersion=VERSION) const
void Serialize(Stream& s, int nType=0, int nVersion=PROTOCOL_VERSION) const
{
::Serialize(s, getvch(), nType, nVersion);
}
template<typename Stream>
void Unserialize(Stream& s, int nType=0, int nVersion=VERSION)
void Unserialize(Stream& s, int nType=0, int nVersion=PROTOCOL_VERSION)
{
std::vector<unsigned char> vch;
::Unserialize(s, vch, nType, nVersion);

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,41 @@
// Copyright (c) 2010 Satoshi Nakamoto
// Copyright (c) 2011 The Bitcoin developers
// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
#ifndef _BITCOINRPC_H_
#define _BITCOINRPC_H_ 1
#include <string>
#include <map>
#include "json/json_spirit_reader_template.h"
#include "json/json_spirit_writer_template.h"
#include "json/json_spirit_utils.h"
void ThreadRPCServer(void* parg);
int CommandLineRPC(int argc, char *argv[]);
typedef json_spirit::Value(*rpcfn_type)(const json_spirit::Array& params, bool fHelp);
class CRPCCommand
{
public:
std::string name;
rpcfn_type actor;
bool okSafeMode;
};
class CRPCTable
{
private:
std::map<std::string, const CRPCCommand*> mapCommands;
public:
CRPCTable();
const CRPCCommand* operator[](std::string name) const;
std::string help(std::string name) const;
};
extern const CRPCTable tableRPC;
#endif

View File

@@ -1,13 +1,15 @@
// Copyright (c) 2011 The Bitcoin developers
// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
#include <boost/assign/list_of.hpp> // for 'map_list_of()'
#include <boost/foreach.hpp>
#include "headers.h"
#include "checkpoints.h"
#include "main.h"
#include "uint256.h"
namespace Checkpoints
{
typedef std::map<int, uint256> MapCheckpoints;
@@ -30,6 +32,7 @@ namespace Checkpoints
(118000, uint256("0x000000000000774a7f8a7a12dc906ddb9e17e75d684f15e00f8767f9e8f36553"))
(134444, uint256("0x00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe"))
(140700, uint256("0x000000000000033b512028abb90e1626d8b346fd0ed598ac0a3c371138dce2bd"))
(168000, uint256("0x000000000000099e61ea72015e79632f216fe6cb33d7899acb35b75c8303b763"))
;
bool CheckBlock(int nHeight, const uint256& hash)
@@ -52,7 +55,6 @@ namespace Checkpoints
{
if (fTestNet) return NULL;
int64 nResult;
BOOST_REVERSE_FOREACH(const MapCheckpoints::value_type& i, mapCheckpoints)
{
const uint256& hash = i.second;

View File

@@ -1,19 +1,17 @@
// Copyright (c) 2011 The Bitcoin developers
// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_CHECKPOINT_H
#define BITCOIN_CHECKPOINT_H
#include <map>
#include "util.h"
class uint256;
class CBlockIndex;
//
// Block-chain checkpoints are compiled-in sanity checks.
// They are updated every release or three.
//
/** Block-chain checkpoints are compiled-in sanity checks.
* They are updated every release or three.
*/
namespace Checkpoints
{
// Returns true if block passes checkpoint checks

63
src/compat.h Normal file
View File

@@ -0,0 +1,63 @@
// 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.
#ifndef _BITCOIN_COMPAT_H
#define _BITCOIN_COMPAT_H 1
#ifdef WIN32
#define _WIN32_WINNT 0x0501
#define WIN32_LEAN_AND_MEAN 1
#ifndef NOMINMAX
#define NOMINMAX
#endif
#include <winsock2.h>
#include <mswsock.h>
#include <ws2tcpip.h>
#else
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/fcntl.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <net/if.h>
#include <netinet/in.h>
#include <ifaddrs.h>
#endif
typedef u_int SOCKET;
#ifdef WIN32
#define MSG_NOSIGNAL 0
#define MSG_DONTWAIT 0
typedef int socklen_t;
#else
#include "errno.h"
#define WSAGetLastError() errno
#define WSAEINVAL EINVAL
#define WSAEALREADY EALREADY
#define WSAEWOULDBLOCK EWOULDBLOCK
#define WSAEMSGSIZE EMSGSIZE
#define WSAEINTR EINTR
#define WSAEINPROGRESS EINPROGRESS
#define WSAEADDRINUSE EADDRINUSE
#define WSAENOTSOCK EBADF
#define INVALID_SOCKET (SOCKET)(~0)
#define SOCKET_ERROR -1
#endif
inline int myclosesocket(SOCKET& hSocket)
{
if (hSocket == INVALID_SOCKET)
return WSAENOTSOCK;
#ifdef WIN32
int ret = closesocket(hSocket);
#else
int ret = close(hSocket);
#endif
hSocket = INVALID_SOCKET;
return ret;
}
#define closesocket(s) myclosesocket(s)
#endif

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2011 The Bitcoin Developers
// Copyright (c) 2009-2012 The Bitcoin Developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -6,14 +6,11 @@
#include <openssl/evp.h>
#include <vector>
#include <string>
#include "headers.h"
#ifdef WIN32
#include <windows.h>
#endif
#include "crypter.h"
#include "main.h"
#include "util.h"
bool CCrypter::SetKeyFromPassphrase(const SecureString& strKeyData, const std::vector<unsigned char>& chSalt, const unsigned int nRounds, const unsigned int nDerivationMethod)
{
@@ -31,7 +28,7 @@ bool CCrypter::SetKeyFromPassphrase(const SecureString& strKeyData, const std::v
i = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha512(), &chSalt[0],
(unsigned char *)&strKeyData[0], strKeyData.size(), nRounds, chKey, chIV);
if (i != WALLET_CRYPTO_KEY_SIZE)
if (i != (int)WALLET_CRYPTO_KEY_SIZE)
{
memset(&chKey, 0, sizeof chKey);
memset(&chIV, 0, sizeof chIV);
@@ -73,14 +70,16 @@ bool CCrypter::Encrypt(const CKeyingMaterial& vchPlaintext, std::vector<unsigned
EVP_CIPHER_CTX ctx;
bool fOk = true;
EVP_CIPHER_CTX_init(&ctx);
EVP_EncryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, chKey, chIV);
EVP_EncryptUpdate(&ctx, &vchCiphertext[0], &nCLen, &vchPlaintext[0], nLen);
EVP_EncryptFinal_ex(&ctx, (&vchCiphertext[0])+nCLen, &nFLen);
if (fOk) fOk = EVP_EncryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, chKey, chIV);
if (fOk) fOk = EVP_EncryptUpdate(&ctx, &vchCiphertext[0], &nCLen, &vchPlaintext[0], nLen);
if (fOk) fOk = EVP_EncryptFinal_ex(&ctx, (&vchCiphertext[0])+nCLen, &nFLen);
EVP_CIPHER_CTX_cleanup(&ctx);
if (!fOk) return false;
vchCiphertext.resize(nCLen + nFLen);
return true;
}
@@ -98,14 +97,16 @@ bool CCrypter::Decrypt(const std::vector<unsigned char>& vchCiphertext, CKeyingM
EVP_CIPHER_CTX ctx;
bool fOk = true;
EVP_CIPHER_CTX_init(&ctx);
EVP_DecryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, chKey, chIV);
EVP_DecryptUpdate(&ctx, &vchPlaintext[0], &nPLen, &vchCiphertext[0], nLen);
EVP_DecryptFinal_ex(&ctx, (&vchPlaintext[0])+nPLen, &nFLen);
if (fOk) fOk = EVP_DecryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, chKey, chIV);
if (fOk) fOk = EVP_DecryptUpdate(&ctx, &vchPlaintext[0], &nPLen, &vchCiphertext[0], nLen);
if (fOk) fOk = EVP_DecryptFinal_ex(&ctx, (&vchPlaintext[0])+nPLen, &nFLen);
EVP_CIPHER_CTX_cleanup(&ctx);
if (!fOk) return false;
vchPlaintext.resize(nPLen + nFLen);
return true;
}

View File

@@ -1,10 +1,12 @@
// Copyright (c) 2011 The Bitcoin Developers
// Copyright (c) 2009-2012 The Bitcoin Developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef __CRYPTER_H__
#define __CRYPTER_H__
#include "allocators.h" /* for SecureString */
#include "key.h"
#include "serialize.h"
const unsigned int WALLET_CRYPTO_KEY_SIZE = 32;
const unsigned int WALLET_CRYPTO_SALT_SIZE = 8;
@@ -24,6 +26,7 @@ with the double-sha256 of the public key as the IV, and the
master key's key as the encryption key (see keystore.[ch]).
*/
/** Master key for wallet encryption */
class CMasterKey
{
public:
@@ -57,6 +60,7 @@ public:
typedef std::vector<unsigned char, secure_allocator<unsigned char> > CKeyingMaterial;
/** Encryption/decryption context with key information */
class CCrypter
{
private:

View File

@@ -1,20 +1,24 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2011 The Bitcoin developers
// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
#include "headers.h"
#include "db.h"
#include "net.h"
#include "util.h"
#include "main.h"
#include <boost/version.hpp>
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
#ifndef WIN32
#include "sys/stat.h"
#endif
using namespace std;
using namespace boost;
unsigned int nWalletDBUpdated;
uint64 nAccountingEntryNumber = 0;
@@ -22,10 +26,11 @@ uint64 nAccountingEntryNumber = 0;
// CDB
//
static CCriticalSection cs_db;
CCriticalSection cs_db;
static bool fDbEnvInit = false;
bool fDetachDB = false;
DbEnv dbenv(0);
static map<string, int> mapFileUseCount;
map<string, int> mapFileUseCount;
static map<string, Db*> mapDb;
static void EnvShutdown()
@@ -42,7 +47,7 @@ static void EnvShutdown()
{
printf("EnvShutdown exception: %s (%d)\n", e.what(), e.get_errno());
}
DbEnv(0).remove(GetDataDir().c_str(), 0);
DbEnv(0).remove(GetDataDir().string().c_str(), 0);
}
class CDBInit
@@ -59,7 +64,7 @@ public:
instance_of_cdbinit;
CDB::CDB(const char* pszFile, const char* pszMode) : pdb(NULL)
CDB::CDB(const char *pszFile, const char* pszMode) : pdb(NULL)
{
int ret;
if (pszFile == NULL)
@@ -71,25 +76,29 @@ CDB::CDB(const char* pszFile, const char* pszMode) : pdb(NULL)
if (fCreate)
nFlags |= DB_CREATE;
CRITICAL_BLOCK(cs_db)
{
LOCK(cs_db);
if (!fDbEnvInit)
{
if (fShutdown)
return;
string strDataDir = GetDataDir();
string strLogDir = strDataDir + "/database";
filesystem::create_directory(strLogDir.c_str());
string strErrorFile = strDataDir + "/db.log";
printf("dbenv.open strLogDir=%s strErrorFile=%s\n", strLogDir.c_str(), strErrorFile.c_str());
filesystem::path pathDataDir = GetDataDir();
filesystem::path pathLogDir = pathDataDir / "database";
filesystem::create_directory(pathLogDir);
filesystem::path pathErrorFile = pathDataDir / "db.log";
printf("dbenv.open LogDir=%s ErrorFile=%s\n", pathLogDir.string().c_str(), pathErrorFile.string().c_str());
dbenv.set_lg_dir(strLogDir.c_str());
dbenv.set_lg_max(10000000);
int nDbCache = GetArg("-dbcache", 25);
dbenv.set_lg_dir(pathLogDir.string().c_str());
dbenv.set_cachesize(nDbCache / 1024, (nDbCache % 1024)*1048576, 1);
dbenv.set_lg_bsize(1048576);
dbenv.set_lg_max(10485760);
dbenv.set_lk_max_locks(10000);
dbenv.set_lk_max_objects(10000);
dbenv.set_errfile(fopen(strErrorFile.c_str(), "a")); /// debug
dbenv.set_errfile(fopen(pathErrorFile.string().c_str(), "a")); /// debug
dbenv.set_flags(DB_AUTO_COMMIT, 1);
ret = dbenv.open(strDataDir.c_str(),
dbenv.log_set_config(DB_LOG_AUTO_REMOVE, 1);
ret = dbenv.open(pathDataDir.string().c_str(),
DB_CREATE |
DB_INIT_LOCK |
DB_INIT_LOG |
@@ -121,8 +130,10 @@ CDB::CDB(const char* pszFile, const char* pszMode) : pdb(NULL)
{
delete pdb;
pdb = NULL;
CRITICAL_BLOCK(cs_db)
{
LOCK(cs_db);
--mapFileUseCount[strFile];
}
strFile = "";
throw runtime_error(strprintf("CDB() : can't open database file %s, error %d", pszFile, ret));
}
@@ -131,7 +142,7 @@ CDB::CDB(const char* pszFile, const char* pszMode) : pdb(NULL)
{
bool fTmp = fReadOnly;
fReadOnly = false;
WriteVersion(VERSION);
WriteVersion(CLIENT_VERSION);
fReadOnly = fTmp;
}
@@ -155,18 +166,23 @@ void CDB::Close()
nMinutes = 1;
if (strFile == "addr.dat")
nMinutes = 2;
if (strFile == "blkindex.dat" && IsInitialBlockDownload() && nBestHeight % 500 != 0)
nMinutes = 1;
dbenv.txn_checkpoint(0, nMinutes, 0);
if (strFile == "blkindex.dat")
nMinutes = 2;
if (strFile == "blkindex.dat" && IsInitialBlockDownload())
nMinutes = 5;
CRITICAL_BLOCK(cs_db)
dbenv.txn_checkpoint(nMinutes ? GetArg("-dblogsize", 100)*1024 : 0, nMinutes, 0);
{
LOCK(cs_db);
--mapFileUseCount[strFile];
}
}
void static CloseDb(const string& strFile)
void CloseDb(const string& strFile)
{
CRITICAL_BLOCK(cs_db)
{
LOCK(cs_db);
if (mapDb[strFile] != NULL)
{
// Close the database handle
@@ -182,8 +198,8 @@ bool CDB::Rewrite(const string& strFile, const char* pszSkip)
{
while (!fShutdown)
{
CRITICAL_BLOCK(cs_db)
{
LOCK(cs_db);
if (!mapFileUseCount.count(strFile) || mapFileUseCount[strFile] == 0)
{
// Flush log data to the dat file
@@ -215,8 +231,8 @@ bool CDB::Rewrite(const string& strFile, const char* pszSkip)
if (pcursor)
while (fSuccess)
{
CDataStream ssKey;
CDataStream ssValue;
CDataStream ssKey(SER_DISK, CLIENT_VERSION);
CDataStream ssValue(SER_DISK, CLIENT_VERSION);
int ret = db.ReadAtCursor(pcursor, ssKey, ssValue, DB_NEXT);
if (ret == DB_NOTFOUND)
{
@@ -236,7 +252,7 @@ bool CDB::Rewrite(const string& strFile, const char* pszSkip)
{
// Update version:
ssValue.clear();
ssValue << VERSION;
ssValue << CLIENT_VERSION;
}
Dbt datKey(&ssKey[0], ssKey.size());
Dbt datValue(&ssValue[0], ssValue.size());
@@ -280,8 +296,8 @@ void DBFlush(bool fShutdown)
printf("DBFlush(%s)%s\n", fShutdown ? "true" : "false", fDbEnvInit ? "" : " db not started");
if (!fDbEnvInit)
return;
CRITICAL_BLOCK(cs_db)
{
LOCK(cs_db);
map<string, int>::iterator mi = mapFileUseCount.begin();
while (mi != mapFileUseCount.end())
{
@@ -292,9 +308,13 @@ void DBFlush(bool fShutdown)
{
// Move log data to the dat file
CloseDb(strFile);
printf("%s checkpoint\n", strFile.c_str());
dbenv.txn_checkpoint(0, 0, 0);
printf("%s flush\n", strFile.c_str());
dbenv.lsn_reset(strFile.c_str(), 0);
if ((strFile != "blkindex.dat" && strFile != "addr.dat") || fDetachDB) {
printf("%s detach\n", strFile.c_str());
dbenv.lsn_reset(strFile.c_str(), 0);
}
printf("%s closed\n", strFile.c_str());
mapFileUseCount.erase(mi++);
}
else
@@ -372,10 +392,10 @@ bool CTxDB::ReadOwnerTxes(uint160 hash160, int nMinHeight, vector<CTransaction>&
loop
{
// Read next record
CDataStream ssKey;
CDataStream ssKey(SER_DISK, CLIENT_VERSION);
if (fFlags == DB_SET_RANGE)
ssKey << string("owner") << hash160 << CDiskTxPos(0, 0, 0);
CDataStream ssValue;
CDataStream ssValue(SER_DISK, CLIENT_VERSION);
int ret = ReadAtCursor(pcursor, ssKey, ssValue, fFlags);
fFlags = DB_NEXT;
if (ret == DB_NOTFOUND)
@@ -500,10 +520,10 @@ bool CTxDB::LoadBlockIndex()
loop
{
// Read next record
CDataStream ssKey;
CDataStream ssKey(SER_DISK, CLIENT_VERSION);
if (fFlags == DB_SET_RANGE)
ssKey << make_pair(string("blockindex"), uint256(0));
CDataStream ssValue;
CDataStream ssValue(SER_DISK, CLIENT_VERSION);
int ret = ReadAtCursor(pcursor, ssKey, ssValue, fFlags);
fFlags = DB_NEXT;
if (ret == DB_NOTFOUND)
@@ -514,7 +534,7 @@ bool CTxDB::LoadBlockIndex()
// Unserialize
string strType;
ssKey >> strType;
if (strType == "blockindex")
if (strType == "blockindex" && !fRequestShutdown)
{
CDiskBlockIndex diskindex;
ssValue >> diskindex;
@@ -541,11 +561,14 @@ bool CTxDB::LoadBlockIndex()
}
else
{
break;
break; // if shutdown requested or finished loading block index
}
}
pcursor->close();
if (fRequestShutdown)
return true;
// Calculate bnChainWork
vector<pair<int, CBlockIndex*> > vSortedByHeight;
vSortedByHeight.reserve(mapBlockIndex.size());
@@ -579,19 +602,118 @@ bool CTxDB::LoadBlockIndex()
ReadBestInvalidWork(bnBestInvalidWork);
// Verify blocks in the best chain
int nCheckLevel = GetArg("-checklevel", 1);
int nCheckDepth = GetArg( "-checkblocks", 2500);
if (nCheckDepth == 0)
nCheckDepth = 1000000000; // suffices until the year 19000
if (nCheckDepth > nBestHeight)
nCheckDepth = nBestHeight;
printf("Verifying last %i blocks at level %i\n", nCheckDepth, nCheckLevel);
CBlockIndex* pindexFork = NULL;
map<pair<unsigned int, unsigned int>, CBlockIndex*> mapBlockPos;
for (CBlockIndex* pindex = pindexBest; pindex && pindex->pprev; pindex = pindex->pprev)
{
if (pindex->nHeight < nBestHeight-2500 && !mapArgs.count("-checkblocks"))
if (pindex->nHeight < nBestHeight-nCheckDepth)
break;
CBlock block;
if (!block.ReadFromDisk(pindex))
return error("LoadBlockIndex() : block.ReadFromDisk failed");
if (!block.CheckBlock())
// check level 1: verify block validity
if (nCheckLevel>0 && !block.CheckBlock())
{
printf("LoadBlockIndex() : *** found bad block at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString().c_str());
pindexFork = pindex->pprev;
}
// check level 2: verify transaction index validity
if (nCheckLevel>1)
{
pair<unsigned int, unsigned int> pos = make_pair(pindex->nFile, pindex->nBlockPos);
mapBlockPos[pos] = pindex;
BOOST_FOREACH(const CTransaction &tx, block.vtx)
{
uint256 hashTx = tx.GetHash();
CTxIndex txindex;
if (ReadTxIndex(hashTx, txindex))
{
// check level 3: checker transaction hashes
if (nCheckLevel>2 || pindex->nFile != txindex.pos.nFile || pindex->nBlockPos != txindex.pos.nBlockPos)
{
// either an error or a duplicate transaction
CTransaction txFound;
if (!txFound.ReadFromDisk(txindex.pos))
{
printf("LoadBlockIndex() : *** cannot read mislocated transaction %s\n", hashTx.ToString().c_str());
pindexFork = pindex->pprev;
}
else
if (txFound.GetHash() != hashTx) // not a duplicate tx
{
printf("LoadBlockIndex(): *** invalid tx position for %s\n", hashTx.ToString().c_str());
pindexFork = pindex->pprev;
}
}
// check level 4: check whether spent txouts were spent within the main chain
unsigned int nOutput = 0;
if (nCheckLevel>3)
{
BOOST_FOREACH(const CDiskTxPos &txpos, txindex.vSpent)
{
if (!txpos.IsNull())
{
pair<unsigned int, unsigned int> posFind = make_pair(txpos.nFile, txpos.nBlockPos);
if (!mapBlockPos.count(posFind))
{
printf("LoadBlockIndex(): *** found bad spend at %d, hashBlock=%s, hashTx=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString().c_str(), hashTx.ToString().c_str());
pindexFork = pindex->pprev;
}
// check level 6: check whether spent txouts were spent by a valid transaction that consume them
if (nCheckLevel>5)
{
CTransaction txSpend;
if (!txSpend.ReadFromDisk(txpos))
{
printf("LoadBlockIndex(): *** cannot read spending transaction of %s:%i from disk\n", hashTx.ToString().c_str(), nOutput);
pindexFork = pindex->pprev;
}
else if (!txSpend.CheckTransaction())
{
printf("LoadBlockIndex(): *** spending transaction of %s:%i is invalid\n", hashTx.ToString().c_str(), nOutput);
pindexFork = pindex->pprev;
}
else
{
bool fFound = false;
BOOST_FOREACH(const CTxIn &txin, txSpend.vin)
if (txin.prevout.hash == hashTx && txin.prevout.n == nOutput)
fFound = true;
if (!fFound)
{
printf("LoadBlockIndex(): *** spending transaction of %s:%i does not spend it\n", hashTx.ToString().c_str(), nOutput);
pindexFork = pindex->pprev;
}
}
}
}
nOutput++;
}
}
}
// check level 5: check whether all prevouts are marked spent
if (nCheckLevel>4)
{
BOOST_FOREACH(const CTxIn &txin, tx.vin)
{
CTxIndex txindex;
if (ReadTxIndex(txin.prevout.hash, txindex))
if (txindex.vSpent.size()-1 < txin.prevout.n || txindex.vSpent[txin.prevout.n].IsNull())
{
printf("LoadBlockIndex(): *** found unspent prevout %s:%i in %s\n", txin.prevout.hash.ToString().c_str(), txin.prevout.n, hashTx.ToString().c_str());
pindexFork = pindex->pprev;
}
}
}
}
}
}
if (pindexFork)
{
@@ -615,50 +737,58 @@ bool CTxDB::LoadBlockIndex()
// CAddrDB
//
bool CAddrDB::WriteAddress(const CAddress& addr)
bool CAddrDB::WriteAddrman(const CAddrMan& addrman)
{
return Write(make_pair(string("addr"), addr.GetKey()), addr);
}
bool CAddrDB::EraseAddress(const CAddress& addr)
{
return Erase(make_pair(string("addr"), addr.GetKey()));
return Write(string("addrman"), addrman);
}
bool CAddrDB::LoadAddresses()
{
CRITICAL_BLOCK(cs_mapAddresses)
if (Read(string("addrman"), addrman))
{
// Get cursor
Dbc* pcursor = GetCursor();
if (!pcursor)
printf("Loaded %i addresses\n", addrman.size());
return true;
}
// Read pre-0.6 addr records
vector<CAddress> vAddr;
vector<vector<unsigned char> > vDelete;
// Get cursor
Dbc* pcursor = GetCursor();
if (!pcursor)
return false;
loop
{
// Read next record
CDataStream ssKey(SER_DISK, CLIENT_VERSION);
CDataStream ssValue(SER_DISK, CLIENT_VERSION);
int ret = ReadAtCursor(pcursor, ssKey, ssValue);
if (ret == DB_NOTFOUND)
break;
else if (ret != 0)
return false;
loop
// Unserialize
string strType;
ssKey >> strType;
if (strType == "addr")
{
// Read next record
CDataStream ssKey;
CDataStream ssValue;
int ret = ReadAtCursor(pcursor, ssKey, ssValue);
if (ret == DB_NOTFOUND)
break;
else if (ret != 0)
return false;
// Unserialize
string strType;
ssKey >> strType;
if (strType == "addr")
{
CAddress addr;
ssValue >> addr;
mapAddresses.insert(make_pair(addr.GetKey(), addr));
}
CAddress addr;
ssValue >> addr;
vAddr.push_back(addr);
}
pcursor->close();
printf("Loaded %d addresses\n", mapAddresses.size());
}
pcursor->close();
addrman.Add(vAddr, CNetAddr("0.0.0.0"));
printf("Loaded %i addresses\n", addrman.size());
// Note: old records left; we ran into hangs-on-startup
// bugs for some users who (we think) were running after
// an unclean shutdown.
return true;
}
@@ -669,397 +799,3 @@ bool LoadAddresses()
}
//
// CWalletDB
//
bool CWalletDB::WriteName(const string& strAddress, const string& strName)
{
nWalletDBUpdated++;
return Write(make_pair(string("name"), strAddress), strName);
}
bool CWalletDB::EraseName(const string& strAddress)
{
// This should only be used for sending addresses, never for receiving addresses,
// receiving addresses must always have an address book entry if they're not change return.
nWalletDBUpdated++;
return Erase(make_pair(string("name"), strAddress));
}
bool CWalletDB::ReadAccount(const string& strAccount, CAccount& account)
{
account.SetNull();
return Read(make_pair(string("acc"), strAccount), account);
}
bool CWalletDB::WriteAccount(const string& strAccount, const CAccount& account)
{
return Write(make_pair(string("acc"), strAccount), account);
}
bool CWalletDB::WriteAccountingEntry(const CAccountingEntry& acentry)
{
return Write(boost::make_tuple(string("acentry"), acentry.strAccount, ++nAccountingEntryNumber), acentry);
}
int64 CWalletDB::GetAccountCreditDebit(const string& strAccount)
{
list<CAccountingEntry> entries;
ListAccountCreditDebit(strAccount, entries);
int64 nCreditDebit = 0;
BOOST_FOREACH (const CAccountingEntry& entry, entries)
nCreditDebit += entry.nCreditDebit;
return nCreditDebit;
}
void CWalletDB::ListAccountCreditDebit(const string& strAccount, list<CAccountingEntry>& entries)
{
bool fAllAccounts = (strAccount == "*");
Dbc* pcursor = GetCursor();
if (!pcursor)
throw runtime_error("CWalletDB::ListAccountCreditDebit() : cannot create DB cursor");
unsigned int fFlags = DB_SET_RANGE;
loop
{
// Read next record
CDataStream ssKey;
if (fFlags == DB_SET_RANGE)
ssKey << boost::make_tuple(string("acentry"), (fAllAccounts? string("") : strAccount), uint64(0));
CDataStream ssValue;
int ret = ReadAtCursor(pcursor, ssKey, ssValue, fFlags);
fFlags = DB_NEXT;
if (ret == DB_NOTFOUND)
break;
else if (ret != 0)
{
pcursor->close();
throw runtime_error("CWalletDB::ListAccountCreditDebit() : error scanning DB");
}
// Unserialize
string strType;
ssKey >> strType;
if (strType != "acentry")
break;
CAccountingEntry acentry;
ssKey >> acentry.strAccount;
if (!fAllAccounts && acentry.strAccount != strAccount)
break;
ssValue >> acentry;
entries.push_back(acentry);
}
pcursor->close();
}
int CWalletDB::LoadWallet(CWallet* pwallet)
{
pwallet->vchDefaultKey.clear();
int nFileVersion = 0;
vector<uint256> vWalletUpgrade;
bool fIsEncrypted = false;
// Modify defaults
#ifndef WIN32
// Tray icon sometimes disappears on 9.10 karmic koala 64-bit, leaving no way to access the program
fMinimizeToTray = false;
fMinimizeOnClose = false;
#endif
//// todo: shouldn't we catch exceptions and try to recover and continue?
CRITICAL_BLOCK(pwallet->cs_wallet)
{
// Get cursor
Dbc* pcursor = GetCursor();
if (!pcursor)
return DB_CORRUPT;
loop
{
// Read next record
CDataStream ssKey;
CDataStream ssValue;
int ret = ReadAtCursor(pcursor, ssKey, ssValue);
if (ret == DB_NOTFOUND)
break;
else if (ret != 0)
return DB_CORRUPT;
// Unserialize
// Taking advantage of the fact that pair serialization
// is just the two items serialized one after the other
string strType;
ssKey >> strType;
if (strType == "name")
{
string strAddress;
ssKey >> strAddress;
ssValue >> pwallet->mapAddressBook[strAddress];
}
else if (strType == "tx")
{
uint256 hash;
ssKey >> hash;
CWalletTx& wtx = pwallet->mapWallet[hash];
ssValue >> wtx;
wtx.pwallet = pwallet;
if (wtx.GetHash() != hash)
printf("Error in wallet.dat, hash mismatch\n");
// Undo serialize changes in 31600
if (31404 <= wtx.fTimeReceivedIsTxTime && wtx.fTimeReceivedIsTxTime <= 31703)
{
if (!ssValue.empty())
{
char fTmp;
char fUnused;
ssValue >> fTmp >> fUnused >> wtx.strFromAccount;
printf("LoadWallet() upgrading tx ver=%d %d '%s' %s\n", wtx.fTimeReceivedIsTxTime, fTmp, wtx.strFromAccount.c_str(), hash.ToString().c_str());
wtx.fTimeReceivedIsTxTime = fTmp;
}
else
{
printf("LoadWallet() repairing tx ver=%d %s\n", wtx.fTimeReceivedIsTxTime, hash.ToString().c_str());
wtx.fTimeReceivedIsTxTime = 0;
}
vWalletUpgrade.push_back(hash);
}
//// debug print
//printf("LoadWallet %s\n", wtx.GetHash().ToString().c_str());
//printf(" %12I64d %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(),
// wtx.mapValue["message"].c_str());
}
else if (strType == "acentry")
{
string strAccount;
ssKey >> strAccount;
uint64 nNumber;
ssKey >> nNumber;
if (nNumber > nAccountingEntryNumber)
nAccountingEntryNumber = nNumber;
}
else if (strType == "key" || strType == "wkey")
{
vector<unsigned char> vchPubKey;
ssKey >> vchPubKey;
CKey key;
if (strType == "key")
{
CPrivKey pkey;
ssValue >> pkey;
key.SetPrivKey(pkey);
}
else
{
CWalletKey wkey;
ssValue >> wkey;
key.SetPrivKey(wkey.vchPrivKey);
}
if (!pwallet->LoadKey(key))
return DB_CORRUPT;
}
else if (strType == "mkey")
{
unsigned int nID;
ssKey >> nID;
CMasterKey kMasterKey;
ssValue >> kMasterKey;
if(pwallet->mapMasterKeys.count(nID) != 0)
return DB_CORRUPT;
pwallet->mapMasterKeys[nID] = kMasterKey;
if (pwallet->nMasterKeyMaxID < nID)
pwallet->nMasterKeyMaxID = nID;
}
else if (strType == "ckey")
{
vector<unsigned char> vchPubKey;
ssKey >> vchPubKey;
vector<unsigned char> vchPrivKey;
ssValue >> vchPrivKey;
if (!pwallet->LoadCryptedKey(vchPubKey, vchPrivKey))
return DB_CORRUPT;
fIsEncrypted = true;
}
else if (strType == "defaultkey")
{
ssValue >> pwallet->vchDefaultKey;
}
else if (strType == "pool")
{
int64 nIndex;
ssKey >> nIndex;
pwallet->setKeyPool.insert(nIndex);
}
else if (strType == "version")
{
ssValue >> nFileVersion;
if (nFileVersion == 10300)
nFileVersion = 300;
}
else if (strType == "setting")
{
string strKey;
ssKey >> strKey;
// Options
#ifndef QT_GUI
if (strKey == "fGenerateBitcoins") ssValue >> fGenerateBitcoins;
#endif
if (strKey == "nTransactionFee") ssValue >> nTransactionFee;
if (strKey == "fLimitProcessors") ssValue >> fLimitProcessors;
if (strKey == "nLimitProcessors") ssValue >> nLimitProcessors;
if (strKey == "fMinimizeToTray") ssValue >> fMinimizeToTray;
if (strKey == "fMinimizeOnClose") ssValue >> fMinimizeOnClose;
if (strKey == "fUseProxy") ssValue >> fUseProxy;
if (strKey == "addrProxy") ssValue >> addrProxy;
if (fHaveUPnP && strKey == "fUseUPnP") ssValue >> fUseUPnP;
}
else if (strType == "minversion")
{
int nMinVersion = 0;
ssValue >> nMinVersion;
if (nMinVersion > VERSION)
return DB_TOO_NEW;
}
}
pcursor->close();
}
BOOST_FOREACH(uint256 hash, vWalletUpgrade)
WriteTx(hash, pwallet->mapWallet[hash]);
printf("nFileVersion = %d\n", nFileVersion);
printf("fGenerateBitcoins = %d\n", fGenerateBitcoins);
printf("nTransactionFee = %"PRI64d"\n", nTransactionFee);
printf("fMinimizeToTray = %d\n", fMinimizeToTray);
printf("fMinimizeOnClose = %d\n", fMinimizeOnClose);
printf("fUseProxy = %d\n", fUseProxy);
printf("addrProxy = %s\n", addrProxy.ToString().c_str());
if (fHaveUPnP)
printf("fUseUPnP = %d\n", fUseUPnP);
// Rewrite encrypted wallets of versions 0.4.0 and 0.5.0rc:
if (fIsEncrypted && (nFileVersion == 40000 || nFileVersion == 50000))
return DB_NEED_REWRITE;
if (nFileVersion < VERSION) // Update
{
// Get rid of old debug.log file in current directory
if (nFileVersion <= 105 && !pszSetDataDir[0])
unlink("debug.log");
WriteVersion(VERSION);
}
return DB_LOAD_OK;
}
void ThreadFlushWalletDB(void* parg)
{
const string& strFile = ((const string*)parg)[0];
static bool fOneThread;
if (fOneThread)
return;
fOneThread = true;
if (mapArgs.count("-noflushwallet"))
return;
unsigned int nLastSeen = nWalletDBUpdated;
unsigned int nLastFlushed = nWalletDBUpdated;
int64 nLastWalletUpdate = GetTime();
while (!fShutdown)
{
Sleep(500);
if (nLastSeen != nWalletDBUpdated)
{
nLastSeen = nWalletDBUpdated;
nLastWalletUpdate = GetTime();
}
if (nLastFlushed != nWalletDBUpdated && GetTime() - nLastWalletUpdate >= 2)
{
TRY_CRITICAL_BLOCK(cs_db)
{
// Don't do this if any databases are in use
int nRefCount = 0;
map<string, int>::iterator mi = mapFileUseCount.begin();
while (mi != mapFileUseCount.end())
{
nRefCount += (*mi).second;
mi++;
}
if (nRefCount == 0 && !fShutdown)
{
map<string, int>::iterator mi = mapFileUseCount.find(strFile);
if (mi != mapFileUseCount.end())
{
printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
printf("Flushing wallet.dat\n");
nLastFlushed = nWalletDBUpdated;
int64 nStart = GetTimeMillis();
// Flush wallet.dat so it's self contained
CloseDb(strFile);
dbenv.txn_checkpoint(0, 0, 0);
dbenv.lsn_reset(strFile.c_str(), 0);
mapFileUseCount.erase(mi++);
printf("Flushed wallet.dat %"PRI64d"ms\n", GetTimeMillis() - nStart);
}
}
}
}
}
}
bool BackupWallet(const CWallet& wallet, const string& strDest)
{
if (!wallet.fFileBacked)
return false;
while (!fShutdown)
{
CRITICAL_BLOCK(cs_db)
{
if (!mapFileUseCount.count(wallet.strWalletFile) || mapFileUseCount[wallet.strWalletFile] == 0)
{
// Flush log data to the dat file
CloseDb(wallet.strWalletFile);
dbenv.txn_checkpoint(0, 0, 0);
dbenv.lsn_reset(wallet.strWalletFile.c_str(), 0);
mapFileUseCount.erase(wallet.strWalletFile);
// Copy wallet.dat
filesystem::path pathSrc(GetDataDir() + "/" + wallet.strWalletFile);
filesystem::path pathDest(strDest);
if (filesystem::is_directory(pathDest))
pathDest = pathDest / wallet.strWalletFile;
#if BOOST_VERSION >= 104000
filesystem::copy_file(pathSrc, pathDest, filesystem::copy_option::overwrite_if_exists);
#else
filesystem::copy_file(pathSrc, pathDest);
#endif
printf("copied wallet.dat to %s\n", pathDest.string().c_str());
return true;
}
}
Sleep(100);
}
return false;
}

210
src/db.h
View File

@@ -1,11 +1,11 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2011 The Bitcoin developers
// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_DB_H
#define BITCOIN_DB_H
#include "key.h"
#include "main.h"
#include <map>
#include <string>
@@ -13,19 +13,19 @@
#include <db_cxx.h>
class CTxIndex;
class CAddress;
class CAddrMan;
class CBlockLocator;
class CDiskBlockIndex;
class CDiskTxPos;
class CMasterKey;
class COutPoint;
class CAddress;
class CWalletTx;
class CTxIndex;
class CWallet;
class CAccount;
class CAccountingEntry;
class CBlockLocator;
class CWalletTx;
extern unsigned int nWalletDBUpdated;
extern bool fDetachDB;
extern DbEnv dbenv;
extern void DBFlush(bool fShutdown);
@@ -33,7 +33,7 @@ void ThreadFlushWalletDB(void* parg);
bool BackupWallet(const CWallet& wallet, const std::string& strDest);
/** RAII class that provides access to a Berkeley database */
class CDB
{
protected:
@@ -58,7 +58,7 @@ protected:
return false;
// Key
CDataStream ssKey(SER_DISK);
CDataStream ssKey(SER_DISK, CLIENT_VERSION);
ssKey.reserve(1000);
ssKey << key;
Dbt datKey(&ssKey[0], ssKey.size());
@@ -72,7 +72,7 @@ protected:
return false;
// Unserialize value
CDataStream ssValue((char*)datValue.get_data(), (char*)datValue.get_data() + datValue.get_size(), SER_DISK);
CDataStream ssValue((char*)datValue.get_data(), (char*)datValue.get_data() + datValue.get_size(), SER_DISK, CLIENT_VERSION);
ssValue >> value;
// Clear and free memory
@@ -90,13 +90,13 @@ protected:
assert(!"Write called on database in read-only mode");
// Key
CDataStream ssKey(SER_DISK);
CDataStream ssKey(SER_DISK, CLIENT_VERSION);
ssKey.reserve(1000);
ssKey << key;
Dbt datKey(&ssKey[0], ssKey.size());
// Value
CDataStream ssValue(SER_DISK);
CDataStream ssValue(SER_DISK, CLIENT_VERSION);
ssValue.reserve(10000);
ssValue << value;
Dbt datValue(&ssValue[0], ssValue.size());
@@ -119,7 +119,7 @@ protected:
assert(!"Erase called on database in read-only mode");
// Key
CDataStream ssKey(SER_DISK);
CDataStream ssKey(SER_DISK, CLIENT_VERSION);
ssKey.reserve(1000);
ssKey << key;
Dbt datKey(&ssKey[0], ssKey.size());
@@ -139,7 +139,7 @@ protected:
return false;
// Key
CDataStream ssKey(SER_DISK);
CDataStream ssKey(SER_DISK, CLIENT_VERSION);
ssKey.reserve(1000);
ssKey << key;
Dbt datKey(&ssKey[0], ssKey.size());
@@ -265,7 +265,7 @@ public:
/** Access to the transaction database (blkindex.dat) */
class CTxDB : public CDB
{
public:
@@ -296,7 +296,7 @@ public:
/** Access to the (IP) address database (addr.dat) */
class CAddrDB : public CDB
{
public:
@@ -305,181 +305,11 @@ private:
CAddrDB(const CAddrDB&);
void operator=(const CAddrDB&);
public:
bool WriteAddress(const CAddress& addr);
bool EraseAddress(const CAddress& addr);
bool WriteAddrman(const CAddrMan& addr);
bool LoadAddresses();
};
bool LoadAddresses();
class CKeyPool
{
public:
int64 nTime;
std::vector<unsigned char> vchPubKey;
CKeyPool()
{
nTime = GetTime();
}
CKeyPool(const std::vector<unsigned char>& vchPubKeyIn)
{
nTime = GetTime();
vchPubKey = vchPubKeyIn;
}
IMPLEMENT_SERIALIZE
(
if (!(nType & SER_GETHASH))
READWRITE(nVersion);
READWRITE(nTime);
READWRITE(vchPubKey);
)
};
enum DBErrors
{
DB_LOAD_OK,
DB_CORRUPT,
DB_TOO_NEW,
DB_LOAD_FAIL,
DB_NEED_REWRITE
};
class CWalletDB : public CDB
{
public:
CWalletDB(std::string strFilename, const char* pszMode="r+") : CDB(strFilename.c_str(), pszMode)
{
}
private:
CWalletDB(const CWalletDB&);
void operator=(const CWalletDB&);
public:
bool ReadName(const std::string& strAddress, std::string& strName)
{
strName = "";
return Read(std::make_pair(std::string("name"), strAddress), strName);
}
bool WriteName(const std::string& strAddress, const std::string& strName);
bool EraseName(const std::string& strAddress);
bool ReadTx(uint256 hash, CWalletTx& wtx)
{
return Read(std::make_pair(std::string("tx"), hash), wtx);
}
bool WriteTx(uint256 hash, const CWalletTx& wtx)
{
nWalletDBUpdated++;
return Write(std::make_pair(std::string("tx"), hash), wtx);
}
bool EraseTx(uint256 hash)
{
nWalletDBUpdated++;
return Erase(std::make_pair(std::string("tx"), hash));
}
bool ReadKey(const std::vector<unsigned char>& vchPubKey, CPrivKey& vchPrivKey)
{
vchPrivKey.clear();
return Read(std::make_pair(std::string("key"), vchPubKey), vchPrivKey);
}
bool WriteKey(const std::vector<unsigned char>& vchPubKey, const CPrivKey& vchPrivKey)
{
nWalletDBUpdated++;
return Write(std::make_pair(std::string("key"), vchPubKey), vchPrivKey, false);
}
bool WriteCryptedKey(const std::vector<unsigned char>& vchPubKey, const std::vector<unsigned char>& vchCryptedSecret, bool fEraseUnencryptedKey = true)
{
nWalletDBUpdated++;
if (!Write(std::make_pair(std::string("ckey"), vchPubKey), vchCryptedSecret, false))
return false;
if (fEraseUnencryptedKey)
{
Erase(std::make_pair(std::string("key"), vchPubKey));
Erase(std::make_pair(std::string("wkey"), vchPubKey));
}
return true;
}
bool WriteMasterKey(unsigned int nID, const CMasterKey& kMasterKey)
{
nWalletDBUpdated++;
return Write(std::make_pair(std::string("mkey"), nID), kMasterKey, true);
}
bool WriteBestBlock(const CBlockLocator& locator)
{
nWalletDBUpdated++;
return Write(std::string("bestblock"), locator);
}
bool ReadBestBlock(CBlockLocator& locator)
{
return Read(std::string("bestblock"), locator);
}
bool ReadDefaultKey(std::vector<unsigned char>& vchPubKey)
{
vchPubKey.clear();
return Read(std::string("defaultkey"), vchPubKey);
}
bool WriteDefaultKey(const std::vector<unsigned char>& vchPubKey)
{
nWalletDBUpdated++;
return Write(std::string("defaultkey"), vchPubKey);
}
bool ReadPool(int64 nPool, CKeyPool& keypool)
{
return Read(std::make_pair(std::string("pool"), nPool), keypool);
}
bool WritePool(int64 nPool, const CKeyPool& keypool)
{
nWalletDBUpdated++;
return Write(std::make_pair(std::string("pool"), nPool), keypool);
}
bool ErasePool(int64 nPool)
{
nWalletDBUpdated++;
return Erase(std::make_pair(std::string("pool"), nPool));
}
template<typename T>
bool ReadSetting(const std::string& strKey, T& value)
{
return Read(std::make_pair(std::string("setting"), strKey), value);
}
template<typename T>
bool WriteSetting(const std::string& strKey, const T& value)
{
nWalletDBUpdated++;
return Write(std::make_pair(std::string("setting"), strKey), value);
}
bool ReadAccount(const std::string& strAccount, CAccount& account);
bool WriteAccount(const std::string& strAccount, const CAccount& account);
bool WriteAccountingEntry(const CAccountingEntry& acentry);
int64 GetAccountCreditDebit(const std::string& strAccount);
void ListAccountCreditDebit(const std::string& strAccount, std::list<CAccountingEntry>& acentries);
int LoadWallet(CWallet* pwallet);
};
#endif
#endif // BITCOIN_DB_H

View File

@@ -1,98 +0,0 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2011 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
#ifdef _MSC_VER
#pragma warning(disable:4786)
#pragma warning(disable:4804)
#pragma warning(disable:4805)
#pragma warning(disable:4717)
#endif
#ifdef _WIN32_WINNT
#undef _WIN32_WINNT
#endif
#define _WIN32_WINNT 0x0500
#ifdef _WIN32_IE
#undef _WIN32_IE
#endif
#define _WIN32_IE 0x0400
#define WIN32_LEAN_AND_MEAN 1
// Include boost/foreach here as it defines __STDC_LIMIT_MACROS on some systems.
#include <boost/foreach.hpp>
#ifndef __STDC_LIMIT_MACROS
#define __STDC_LIMIT_MACROS // to enable UINT64_MAX from stdint.h
#endif
#if (defined(__unix__) || defined(unix)) && !defined(USG)
#include <sys/param.h> // to get BSD define
#endif
#ifdef MAC_OSX
#ifndef BSD
#define BSD 1
#endif
#endif
#include <openssl/buffer.h>
#include <openssl/ecdsa.h>
#include <openssl/evp.h>
#include <openssl/rand.h>
#include <openssl/sha.h>
#include <openssl/ripemd.h>
#include <db_cxx.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <limits.h>
#include <float.h>
#include <assert.h>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <list>
#include <deque>
#include <map>
#ifdef WIN32
#include <windows.h>
#include <winsock2.h>
#include <mswsock.h>
#include <shlobj.h>
#include <shlwapi.h>
#include <io.h>
#include <process.h>
#include <malloc.h>
#else
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#include <errno.h>
#include <net/if.h>
#include <ifaddrs.h>
#include <fcntl.h>
#include <signal.h>
#endif
#ifdef BSD
#include <netinet/in.h>
#endif
#pragma hdrstop
#include "serialize.h"
#include "uint256.h"
#include "util.h"
#include "bignum.h"
#include "base58.h"
#include "main.h"
#ifdef QT_GUI
#include "qtui.h"
#else
#include "noui.h"
#endif

View File

@@ -1,25 +1,21 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2011 The Bitcoin developers
// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
#include "headers.h"
#include "db.h"
#include "walletdb.h"
#include "bitcoinrpc.h"
#include "net.h"
#include "init.h"
#include "strlcpy.h"
#include "util.h"
#include "ui_interface.h"
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
#include <boost/filesystem/convenience.hpp>
#include <boost/interprocess/sync/file_lock.hpp>
#if defined(BITCOIN_NEED_QT_PLUGINS) && !defined(_BITCOIN_QT_PLUGINS_INCLUDED)
#define _BITCOIN_QT_PLUGINS_INCLUDED
#define __INSURE__
#include <QtPlugin>
Q_IMPORT_PLUGIN(qcncodecs)
Q_IMPORT_PLUGIN(qjpcodecs)
Q_IMPORT_PLUGIN(qtwcodecs)
Q_IMPORT_PLUGIN(qkrcodecs)
#ifndef WIN32
#include <signal.h>
#endif
using namespace std;
@@ -45,10 +41,13 @@ void Shutdown(void* parg)
static CCriticalSection cs_Shutdown;
static bool fTaken;
bool fFirstThread = false;
TRY_CRITICAL_BLOCK(cs_Shutdown)
{
fFirstThread = !fTaken;
fTaken = true;
TRY_LOCK(cs_Shutdown, lockShutdown);
if (lockShutdown)
{
fFirstThread = !fTaken;
fTaken = true;
}
}
static bool fExit;
if (fFirstThread)
@@ -148,24 +147,16 @@ bool AppInit2(int argc, char* argv[])
//
// Parameters
//
// If Qt is used, parameters/bitcoin.conf are parsed in qt/bitcoin.cpp's main()
#if !defined(QT_GUI)
ParseParameters(argc, argv);
if (mapArgs.count("-datadir"))
if (!boost::filesystem::is_directory(GetDataDir(false)))
{
if (filesystem::is_directory(filesystem::system_complete(mapArgs["-datadir"])))
{
filesystem::path pathDataDir = filesystem::system_complete(mapArgs["-datadir"]);
strlcpy(pszSetDataDir, pathDataDir.string().c_str(), sizeof(pszSetDataDir));
}
else
{
fprintf(stderr, "Error: Specified directory does not exist\n");
Shutdown(NULL);
}
fprintf(stderr, "Error: Specified directory does not exist\n");
Shutdown(NULL);
}
ReadConfigFile(mapArgs, mapMultiArgs); // Must be done after processing datadir
ReadConfigFile(mapArgs, mapMultiArgs);
#endif
if (mapArgs.count("-?") || mapArgs.count("--help"))
{
@@ -173,80 +164,101 @@ bool AppInit2(int argc, char* argv[])
_("Bitcoin version") + " " + FormatFullVersion() + "\n\n" +
_("Usage:") + "\t\t\t\t\t\t\t\t\t\t\n" +
" bitcoind [options] \t " + "\n" +
" bitcoind [options] <command> [params]\t " + _("Send command to -server or bitcoind\n") +
" bitcoind [options] help \t\t " + _("List commands\n") +
" bitcoind [options] help <command> \t\t " + _("Get help for a command\n") +
_("Options:\n") +
" -conf=<file> \t\t " + _("Specify configuration file (default: bitcoin.conf)\n") +
" -pid=<file> \t\t " + _("Specify pid file (default: bitcoind.pid)\n") +
" -gen \t\t " + _("Generate coins\n") +
" -gen=0 \t\t " + _("Don't generate coins\n") +
" -min \t\t " + _("Start minimized\n") +
" -datadir=<dir> \t\t " + _("Specify data directory\n") +
" -timeout=<n> \t " + _("Specify connection timeout (in milliseconds)\n") +
" -proxy=<ip:port> \t " + _("Connect through socks4 proxy\n") +
" -dns \t " + _("Allow DNS lookups for addnode and connect\n") +
" -port=<port> \t\t " + _("Listen for connections on <port> (default: 8333 or testnet: 18333)\n") +
" -maxconnections=<n>\t " + _("Maintain at most <n> connections to peers (default: 125)\n") +
" -addnode=<ip> \t " + _("Add a node to connect to\n") +
" -connect=<ip> \t\t " + _("Connect only to the specified node\n") +
" -nolisten \t " + _("Don't accept connections from outside\n") +
" -nodnsseed \t " + _("Don't bootstrap list of peers using DNS\n") +
" -banscore=<n> \t " + _("Threshold for disconnecting misbehaving peers (default: 100)\n") +
" -bantime=<n> \t " + _("Number of seconds to keep misbehaving peers from reconnecting (default: 86400)\n") +
" -maxreceivebuffer=<n>\t " + _("Maximum per-connection receive buffer, <n>*1000 bytes (default: 10000)\n") +
" -maxsendbuffer=<n>\t " + _("Maximum per-connection send buffer, <n>*1000 bytes (default: 10000)\n") +
" bitcoind [options] <command> [params]\t " + _("Send command to -server or bitcoind") + "\n" +
" bitcoind [options] help \t\t " + _("List commands") + "\n" +
" bitcoind [options] help <command> \t\t " + _("Get help for a command") + "\n" +
_("Options:") + "\n" +
" -conf=<file> \t\t " + _("Specify configuration file (default: bitcoin.conf)") + "\n" +
" -pid=<file> \t\t " + _("Specify pid file (default: bitcoind.pid)") + "\n" +
" -gen \t\t " + _("Generate coins") + "\n" +
" -gen=0 \t\t " + _("Don't generate coins") + "\n" +
" -min \t\t " + _("Start minimized") + "\n" +
" -splash \t\t " + _("Show splash screen on startup (default: 1)") + "\n" +
" -datadir=<dir> \t\t " + _("Specify data directory") + "\n" +
" -dbcache=<n> \t\t " + _("Set database cache size in megabytes (default: 25)") + "\n" +
" -dblogsize=<n> \t\t " + _("Set database disk log size in megabytes (default: 100)") + "\n" +
" -timeout=<n> \t " + _("Specify connection timeout (in milliseconds)") + "\n" +
" -proxy=<ip:port> \t " + _("Connect through socks4 proxy") + "\n" +
" -dns \t " + _("Allow DNS lookups for addnode and connect") + "\n" +
" -port=<port> \t\t " + _("Listen for connections on <port> (default: 8333 or testnet: 18333)") + "\n" +
" -maxconnections=<n>\t " + _("Maintain at most <n> connections to peers (default: 125)") + "\n" +
" -addnode=<ip> \t " + _("Add a node to connect to and attempt to keep the connection open") + "\n" +
" -connect=<ip> \t\t " + _("Connect only to the specified node") + "\n" +
" -irc \t " + _("Find peers using internet relay chat (default: 0)") + "\n" +
" -listen \t " + _("Accept connections from outside (default: 1)") + "\n" +
#ifdef QT_GUI
" -lang=<lang> \t\t " + _("Set language, for example \"de_DE\" (default: system locale)") + "\n" +
#endif
" -dnsseed \t " + _("Find peers using DNS lookup (default: 1)") + "\n" +
" -banscore=<n> \t " + _("Threshold for disconnecting misbehaving peers (default: 100)") + "\n" +
" -bantime=<n> \t " + _("Number of seconds to keep misbehaving peers from reconnecting (default: 86400)") + "\n" +
" -maxreceivebuffer=<n>\t " + _("Maximum per-connection receive buffer, <n>*1000 bytes (default: 10000)") + "\n" +
" -maxsendbuffer=<n>\t " + _("Maximum per-connection send buffer, <n>*1000 bytes (default: 10000)") + "\n" +
#ifdef USE_UPNP
#if USE_UPNP
" -noupnp \t " + _("Don't attempt to use UPnP to map the listening port\n") +
" -upnp \t " + _("Use Universal Plug and Play to map the listening port (default: 1)") + "\n" +
#else
" -upnp \t " + _("Attempt to use UPnP to map the listening port\n") +
" -upnp \t " + _("Use Universal Plug and Play to map the listening port (default: 0)") + "\n" +
#endif
" -detachdb \t " + _("Detach block and address databases. Increases shutdown time (default: 0)") + "\n" +
#endif
" -paytxfee=<amt> \t " + _("Fee per KB to add to transactions you send\n") +
#ifdef GUI
" -server \t\t " + _("Accept command line and JSON-RPC commands\n") +
" -paytxfee=<amt> \t " + _("Fee per KB to add to transactions you send") + "\n" +
#ifdef QT_GUI
" -server \t\t " + _("Accept command line and JSON-RPC commands") + "\n" +
#endif
#ifndef WIN32
" -daemon \t\t " + _("Run in the background as a daemon and accept commands\n") +
#if !defined(WIN32) && !defined(QT_GUI)
" -daemon \t\t " + _("Run in the background as a daemon and accept commands") + "\n" +
#endif
" -testnet \t\t " + _("Use the test network\n") +
" -debug \t\t " + _("Output extra debugging information\n") +
" -logtimestamps \t " + _("Prepend debug output with timestamp\n") +
" -printtoconsole \t " + _("Send trace/debug info to console instead of debug.log file\n") +
" -testnet \t\t " + _("Use the test network") + "\n" +
" -debug \t\t " + _("Output extra debugging information") + "\n" +
" -logtimestamps \t " + _("Prepend debug output with timestamp") + "\n" +
" -printtoconsole \t " + _("Send trace/debug info to console instead of debug.log file") + "\n" +
#ifdef WIN32
" -printtodebugger \t " + _("Send trace/debug info to debugger\n") +
#endif
" -rpcuser=<user> \t " + _("Username for JSON-RPC connections\n") +
" -rpcpassword=<pw>\t " + _("Password for JSON-RPC connections\n") +
" -rpcport=<port> \t\t " + _("Listen for JSON-RPC connections on <port> (default: 8332)\n") +
" -rpcallowip=<ip> \t\t " + _("Allow JSON-RPC connections from specified IP address\n") +
" -rpcconnect=<ip> \t " + _("Send commands to node running on <ip> (default: 127.0.0.1)\n") +
" -keypool=<n> \t " + _("Set key pool size to <n> (default: 100)\n") +
" -rescan \t " + _("Rescan the block chain for missing wallet transactions\n");
#ifdef USE_SSL
strUsage += string() +
_("\nSSL options: (see the Bitcoin Wiki for SSL setup instructions)\n") +
" -rpcssl \t " + _("Use OpenSSL (https) for JSON-RPC connections\n") +
" -rpcsslcertificatechainfile=<file.cert>\t " + _("Server certificate file (default: server.cert)\n") +
" -rpcsslprivatekeyfile=<file.pem> \t " + _("Server private key (default: server.pem)\n") +
" -rpcsslciphers=<ciphers> \t " + _("Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH)\n");
" -printtodebugger \t " + _("Send trace/debug info to debugger") + "\n" +
#endif
" -rpcuser=<user> \t " + _("Username for JSON-RPC connections") + "\n" +
" -rpcpassword=<pw>\t " + _("Password for JSON-RPC connections") + "\n" +
" -rpcport=<port> \t\t " + _("Listen for JSON-RPC connections on <port> (default: 8332)") + "\n" +
" -rpcallowip=<ip> \t\t " + _("Allow JSON-RPC connections from specified IP address") + "\n" +
" -rpcconnect=<ip> \t " + _("Send commands to node running on <ip> (default: 127.0.0.1)") + "\n" +
" -blocknotify=<cmd> " + _("Execute command when the best block changes (%s in cmd is replaced by block hash)") + "\n" +
" -upgradewallet \t " + _("Upgrade wallet to latest format") + "\n" +
" -keypool=<n> \t " + _("Set key pool size to <n> (default: 100)") + "\n" +
" -rescan \t " + _("Rescan the block chain for missing wallet transactions") + "\n" +
" -checkblocks=<n> \t\t " + _("How many blocks to check at startup (default: 2500, 0 = all)") + "\n" +
" -checklevel=<n> \t\t " + _("How thorough the block verification is (0-6, default: 1)") + "\n";
strUsage += string() +
" -? \t\t " + _("This help message\n");
_("\nSSL options: (see the Bitcoin Wiki for SSL setup instructions)") + "\n" +
" -rpcssl \t " + _("Use OpenSSL (https) for JSON-RPC connections") + "\n" +
" -rpcsslcertificatechainfile=<file.cert>\t " + _("Server certificate file (default: server.cert)") + "\n" +
" -rpcsslprivatekeyfile=<file.pem> \t " + _("Server private key (default: server.pem)") + "\n" +
" -rpcsslciphers=<ciphers> \t " + _("Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH)") + "\n";
strUsage += string() +
" -? \t\t " + _("This help message") + "\n";
// Remove tabs
strUsage.erase(std::remove(strUsage.begin(), strUsage.end(), '\t'), strUsage.end());
#if defined(QT_GUI) && defined(WIN32)
// On windows, show a message box, as there is no stderr
ThreadSafeMessageBox(strUsage, _("Usage"), wxOK | wxMODAL);
#else
fprintf(stderr, "%s", strUsage.c_str());
#endif
return false;
}
fDebug = GetBoolArg("-debug");
fAllowDNS = GetBoolArg("-dns");
fTestNet = GetBoolArg("-testnet");
if (fTestNet)
{
SoftSetBoolArg("-irc", true);
}
#ifndef WIN32
fDebug = GetBoolArg("-debug");
fDetachDB = GetBoolArg("-detachdb", false);
#if !defined(WIN32) && !defined(QT_GUI)
fDaemon = GetBoolArg("-daemon");
#else
fDaemon = false;
@@ -263,15 +275,11 @@ bool AppInit2(int argc, char* argv[])
#endif
fPrintToConsole = GetBoolArg("-printtoconsole");
fPrintToDebugger = GetBoolArg("-printtodebugger");
fTestNet = GetBoolArg("-testnet");
bool fTOR = (fUseProxy && addrProxy.port == htons(9050));
fNoListen = GetBoolArg("-nolisten") || fTOR;
fLogTimestamps = GetBoolArg("-logtimestamps");
#ifndef QT_GUI
for (int i = 1; i < argc; i++)
if (!IsSwitchChar(argv[i][0]))
if (!IsSwitchChar(argv[i][0]) && !(strlen(argv[i]) > 7 && strncasecmp(argv[i], "bitcoin:", 8) == 0))
fCommandLine = true;
if (fCommandLine)
@@ -281,7 +289,7 @@ bool AppInit2(int argc, char* argv[])
}
#endif
#ifndef WIN32
#if !defined(WIN32) && !defined(QT_GUI)
if (fDaemon)
{
// Daemonize
@@ -303,11 +311,11 @@ bool AppInit2(int argc, char* argv[])
}
#endif
if (!fDebug && !pszSetDataDir[0])
if (!fDebug)
ShrinkDebugFile();
printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
printf("Bitcoin version %s\n", FormatFullVersion().c_str());
printf("Default data directory %s\n", GetDefaultDataDir().c_str());
printf("Bitcoin version %s (%s)\n", FormatFullVersion().c_str(), CLIENT_DATE.c_str());
printf("Default data directory %s\n", GetDefaultDataDir().string().c_str());
if (GetBoolArg("-loadblockindextest"))
{
@@ -318,47 +326,45 @@ bool AppInit2(int argc, char* argv[])
}
// Make sure only a single bitcoin process is using the data directory.
string strLockFile = GetDataDir() + "/.lock";
FILE* file = fopen(strLockFile.c_str(), "a"); // empty lock file; created if it doesn't exist.
boost::filesystem::path pathLockFile = GetDataDir() / ".lock";
FILE* file = fopen(pathLockFile.string().c_str(), "a"); // empty lock file; created if it doesn't exist.
if (file) fclose(file);
static boost::interprocess::file_lock lock(strLockFile.c_str());
static boost::interprocess::file_lock lock(pathLockFile.string().c_str());
if (!lock.try_lock())
{
wxMessageBox(strprintf(_("Cannot obtain a lock on data directory %s. Bitcoin is probably already running."), GetDataDir().c_str()), "Bitcoin");
ThreadSafeMessageBox(strprintf(_("Cannot obtain a lock on data directory %s. Bitcoin is probably already running."), GetDataDir().string().c_str()), _("Bitcoin"), wxOK|wxMODAL);
return false;
}
// Bind to the port early so we can tell if another instance is already running.
string strErrors;
if (!fNoListen)
{
if (!BindListenPort(strErrors))
{
wxMessageBox(strErrors, "Bitcoin");
return false;
}
}
std::ostringstream strErrors;
//
// Load data files
//
if (fDaemon)
fprintf(stdout, "bitcoin server starting\n");
strErrors = "";
int64 nStart;
InitMessage(_("Loading addresses..."));
printf("Loading addresses...\n");
nStart = GetTimeMillis();
if (!LoadAddresses())
strErrors += _("Error loading addr.dat \n");
strErrors << _("Error loading addr.dat") << "\n";
printf(" addresses %15"PRI64d"ms\n", GetTimeMillis() - nStart);
InitMessage(_("Loading block index..."));
printf("Loading block index...\n");
nStart = GetTimeMillis();
if (!LoadBlockIndex())
strErrors += _("Error loading blkindex.dat \n");
strErrors << _("Error loading blkindex.dat") << "\n";
// as LoadBlockIndex can take several minutes, it's possible the user
// requested to kill bitcoin-qt during the last operation. If so, exit.
// As the program has not fully started yet, Shutdown() is possibly overkill.
if (fRequestShutdown)
{
printf("Shutdown requested. Exiting.\n");
return false;
}
printf(" block index %15"PRI64d"ms\n", GetTimeMillis() - nStart);
InitMessage(_("Loading wallet..."));
@@ -370,18 +376,50 @@ bool AppInit2(int argc, char* argv[])
if (nLoadWalletRet != DB_LOAD_OK)
{
if (nLoadWalletRet == DB_CORRUPT)
strErrors += _("Error loading wallet.dat: Wallet corrupted \n");
strErrors << _("Error loading wallet.dat: Wallet corrupted") << "\n";
else if (nLoadWalletRet == DB_TOO_NEW)
strErrors += _("Error loading wallet.dat: Wallet requires newer version of Bitcoin \n");
strErrors << _("Error loading wallet.dat: Wallet requires newer version of Bitcoin") << "\n";
else if (nLoadWalletRet == DB_NEED_REWRITE)
{
strErrors += _("Wallet needed to be rewritten: restart Bitcoin to complete \n");
wxMessageBox(strErrors, "Bitcoin", wxOK | wxICON_ERROR);
strErrors << _("Wallet needed to be rewritten: restart Bitcoin to complete") << "\n";
printf("%s", strErrors.str().c_str());
ThreadSafeMessageBox(strErrors.str(), _("Bitcoin"), wxOK | wxICON_ERROR | wxMODAL);
return false;
}
else
strErrors += _("Error loading wallet.dat \n");
strErrors << _("Error loading wallet.dat") << "\n";
}
if (GetBoolArg("-upgradewallet", fFirstRun))
{
int nMaxVersion = GetArg("-upgradewallet", 0);
if (nMaxVersion == 0) // the -walletupgrade without argument case
{
printf("Performing wallet upgrade to %i\n", FEATURE_LATEST);
nMaxVersion = CLIENT_VERSION;
pwalletMain->SetMinVersion(FEATURE_LATEST); // permanently upgrade the wallet immediately
}
else
printf("Allowing wallet upgrade up to %i\n", nMaxVersion);
if (nMaxVersion < pwalletMain->GetVersion())
strErrors << _("Cannot downgrade wallet") << "\n";
pwalletMain->SetMaxVersion(nMaxVersion);
}
if (fFirstRun)
{
// Create new keyUser and set as default key
RandAddSeedPerfmon();
std::vector<unsigned char> newDefaultKey;
if (!pwalletMain->GetKeyFromPool(newDefaultKey, false))
strErrors << _("Cannot initialize keypool") << "\n";
pwalletMain->SetDefaultKey(newDefaultKey);
if (!pwalletMain->SetAddressBookName(CBitcoinAddress(pwalletMain->vchDefaultKey), ""))
strErrors << _("Cannot write default address") << "\n";
}
printf("%s", strErrors.str().c_str());
printf(" wallet %15"PRI64d"ms\n", GetTimeMillis() - nStart);
RegisterWallet(pwalletMain);
@@ -408,22 +446,26 @@ bool AppInit2(int argc, char* argv[])
InitMessage(_("Done loading"));
printf("Done loading\n");
//// debug print
printf("mapBlockIndex.size() = %d\n", mapBlockIndex.size());
printf("nBestHeight = %d\n", nBestHeight);
printf("setKeyPool.size() = %d\n", pwalletMain->setKeyPool.size());
printf("mapWallet.size() = %d\n", pwalletMain->mapWallet.size());
printf("mapAddressBook.size() = %d\n", pwalletMain->mapAddressBook.size());
//// debug print
printf("mapBlockIndex.size() = %d\n", mapBlockIndex.size());
printf("nBestHeight = %d\n", nBestHeight);
printf("setKeyPool.size() = %d\n", pwalletMain->setKeyPool.size());
printf("mapWallet.size() = %d\n", pwalletMain->mapWallet.size());
printf("mapAddressBook.size() = %d\n", pwalletMain->mapAddressBook.size());
if (!strErrors.empty())
if (!strErrors.str().empty())
{
wxMessageBox(strErrors, "Bitcoin", wxOK | wxICON_ERROR);
ThreadSafeMessageBox(strErrors.str(), _("Bitcoin"), wxOK | wxICON_ERROR | wxMODAL);
return false;
}
// Add wallet transactions that aren't already in a block to mapTransactions
pwalletMain->ReacceptWalletTransactions();
// Note: Bitcoin-QT stores several settings in the wallet, so we want
// to load the wallet BEFORE parsing command-line arguments, so
// the command-line/bitcoin.conf settings override GUI setting.
//
// Parameters
//
@@ -463,15 +505,44 @@ bool AppInit2(int argc, char* argv[])
return false;
}
fGenerateBitcoins = GetBoolArg("-gen");
if (mapArgs.count("-proxy"))
{
fUseProxy = true;
addrProxy = CAddress(mapArgs["-proxy"]);
addrProxy = CService(mapArgs["-proxy"], 9050);
if (!addrProxy.IsValid())
{
wxMessageBox(_("Invalid -proxy address"), "Bitcoin");
ThreadSafeMessageBox(_("Invalid -proxy address"), _("Bitcoin"), wxOK | wxMODAL);
return false;
}
}
bool fTor = (fUseProxy && addrProxy.GetPort() == 9050);
if (fTor)
{
// Use SoftSetBoolArg here so user can override any of these if they wish.
// Note: the GetBoolArg() calls for all of these must happen later.
SoftSetBoolArg("-listen", false);
SoftSetBoolArg("-irc", false);
SoftSetBoolArg("-dnsseed", false);
SoftSetBoolArg("-upnp", false);
SoftSetBoolArg("-dns", false);
}
fAllowDNS = GetBoolArg("-dns");
fNoListen = !GetBoolArg("-listen", true);
// Continue to put "/P2SH/" in the coinbase to monitor
// BIP16 support.
// This can be removed eventually...
const char* pszP2SH = "/P2SH/";
COINBASE_FLAGS << std::vector<unsigned char>(pszP2SH, pszP2SH+strlen(pszP2SH));
if (!fNoListen)
{
std::string strError;
if (!BindListenPort(strError))
{
ThreadSafeMessageBox(strError, _("Bitcoin"), wxOK | wxMODAL);
return false;
}
}
@@ -480,10 +551,10 @@ bool AppInit2(int argc, char* argv[])
{
BOOST_FOREACH(string strAddr, mapMultiArgs["-addnode"])
{
CAddress addr(strAddr, fAllowDNS);
CAddress addr(CService(strAddr, GetDefaultPort(), fAllowDNS));
addr.nTime = 0; // so it won't relay unless successfully connected
if (addr.IsValid())
AddAddress(addr);
addrman.Add(addr, CNetAddr("127.0.0.1"));
}
}
@@ -491,22 +562,11 @@ bool AppInit2(int argc, char* argv[])
{
if (!ParseMoney(mapArgs["-paytxfee"], nTransactionFee))
{
wxMessageBox(_("Invalid amount for -paytxfee=<amount>"), "Bitcoin");
ThreadSafeMessageBox(_("Invalid amount for -paytxfee=<amount>"), _("Bitcoin"), wxOK | wxMODAL);
return false;
}
if (nTransactionFee > 0.25 * COIN)
wxMessageBox(_("Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction."), "Bitcoin", wxOK | wxICON_EXCLAMATION);
}
if (fHaveUPnP)
{
#if USE_UPNP
if (GetBoolArg("-noupnp"))
fUseUPnP = false;
#else
if (GetBoolArg("-upnp"))
fUseUPnP = true;
#endif
ThreadSafeMessageBox(_("Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction."), _("Bitcoin"), wxOK | wxICON_EXCLAMATION | wxMODAL);
}
//
@@ -518,11 +578,16 @@ bool AppInit2(int argc, char* argv[])
RandAddSeedPerfmon();
if (!CreateThread(StartNode, NULL))
wxMessageBox(_("Error: CreateThread(StartNode) failed"), "Bitcoin");
ThreadSafeMessageBox(_("Error: CreateThread(StartNode) failed"), _("Bitcoin"), wxOK | wxMODAL);
if (fServer)
CreateThread(ThreadRPCServer, NULL);
#ifdef QT_GUI
if (GetStartOnSystemStartup())
SetStartOnSystemStartup(true); // Remove startup links
#endif
#if !defined(QT_GUI)
while (1)
Sleep(5000);
@@ -530,3 +595,4 @@ bool AppInit2(int argc, char* argv[])
return true;
}

View File

@@ -1,14 +1,19 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2011 The Bitcoin developers
// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_INIT_H
#define BITCOIN_INIT_H
#include "wallet.h"
extern CWallet* pwalletMain;
void Shutdown(void* parg);
bool AppInit(int argc, char* argv[]);
bool AppInit2(int argc, char* argv[]);
bool GetStartOnSystemStartup();
bool SetStartOnSystemStartup(bool fAutoStart);
#endif

View File

@@ -1,12 +1,12 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2011 The Bitcoin developers
// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
#include "headers.h"
#include "irc.h"
#include "net.h"
#include "strlcpy.h"
#include "base58.h"
using namespace std;
using namespace boost;
@@ -22,22 +22,25 @@ void ThreadIRCSeed2(void* parg);
#pragma pack(push, 1)
struct ircaddr
{
int ip;
struct in_addr ip;
short port;
};
#pragma pack(pop)
string EncodeAddress(const CAddress& addr)
string EncodeAddress(const CService& addr)
{
struct ircaddr tmp;
tmp.ip = addr.ip;
tmp.port = addr.port;
if (addr.GetInAddr(&tmp.ip))
{
tmp.port = htons(addr.GetPort());
vector<unsigned char> vch(UBEGIN(tmp), UEND(tmp));
return string("u") + EncodeBase58Check(vch);
vector<unsigned char> vch(UBEGIN(tmp), UEND(tmp));
return string("u") + EncodeBase58Check(vch);
}
return "";
}
bool DecodeAddress(string str, CAddress& addr)
bool DecodeAddress(string str, CService& addr)
{
vector<unsigned char> vch;
if (!DecodeBase58Check(str.substr(1), vch))
@@ -48,7 +51,7 @@ bool DecodeAddress(string str, CAddress& addr)
return false;
memcpy(&tmp, &vch[0], sizeof(tmp));
addr = CAddress(tmp.ip, ntohs(tmp.port), NODE_NETWORK);
addr = CService(tmp.ip, ntohs(tmp.port));
return true;
}
@@ -73,57 +76,6 @@ static bool Send(SOCKET hSocket, const char* pszSend)
return true;
}
bool RecvLine(SOCKET hSocket, string& strLine)
{
strLine = "";
loop
{
char c;
int nBytes = recv(hSocket, &c, 1, 0);
if (nBytes > 0)
{
if (c == '\n')
continue;
if (c == '\r')
return true;
strLine += c;
if (strLine.size() >= 9000)
return true;
}
else if (nBytes <= 0)
{
if (fShutdown)
return false;
if (nBytes < 0)
{
int nErr = WSAGetLastError();
if (nErr == WSAEMSGSIZE)
continue;
if (nErr == WSAEWOULDBLOCK || nErr == WSAEINTR || nErr == WSAEINPROGRESS)
{
Sleep(10);
continue;
}
}
if (!strLine.empty())
return true;
if (nBytes == 0)
{
// socket closed
printf("IRC socket closed\n");
return false;
}
else
{
// socket error
int nErr = WSAGetLastError();
printf("IRC recv failed: %d\n", nErr);
return false;
}
}
}
}
bool RecvLineIRC(SOCKET hSocket, string& strLine)
{
loop
@@ -156,13 +108,13 @@ int RecvUntil(SOCKET hSocket, const char* psz1, const char* psz2=NULL, const cha
if (!RecvLineIRC(hSocket, strLine))
return 0;
printf("IRC %s\n", strLine.c_str());
if (psz1 && strLine.find(psz1) != -1)
if (psz1 && strLine.find(psz1) != string::npos)
return 1;
if (psz2 && strLine.find(psz2) != -1)
if (psz2 && strLine.find(psz2) != string::npos)
return 2;
if (psz3 && strLine.find(psz3) != -1)
if (psz3 && strLine.find(psz3) != string::npos)
return 3;
if (psz4 && strLine.find(psz4) != -1)
if (psz4 && strLine.find(psz4) != string::npos)
return 4;
}
}
@@ -204,7 +156,7 @@ bool RecvCodeLine(SOCKET hSocket, const char* psz1, string& strRet)
}
}
bool GetIPFromIRC(SOCKET hSocket, string strMyName, unsigned int& ipRet)
bool GetIPFromIRC(SOCKET hSocket, string strMyName, CNetAddr& ipRet)
{
Send(hSocket, strprintf("USERHOST %s\r", strMyName.c_str()).c_str());
@@ -227,10 +179,10 @@ bool GetIPFromIRC(SOCKET hSocket, string strMyName, unsigned int& ipRet)
printf("GetIPFromIRC() got userhost %s\n", strHost.c_str());
if (fUseProxy)
return false;
CAddress addr(strHost, 0, true);
CNetAddr addr(strHost, true);
if (!addr.IsValid())
return false;
ipRet = addr.ip;
ipRet = addr;
return true;
}
@@ -258,25 +210,21 @@ void ThreadIRCSeed2(void* parg)
if (mapArgs.count("-connect") || fNoListen)
return;
if (GetBoolArg("-noirc"))
if (!GetBoolArg("-irc", false))
return;
printf("ThreadIRCSeed started\n");
int nErrorWait = 10;
int nRetryWait = 10;
bool fNameInUse = false;
bool fTOR = (fUseProxy && addrProxy.port == htons(9050));
while (!fShutdown)
{
//CAddress addrConnect("216.155.130.130:6667"); // chat.freenode.net
CAddress addrConnect("92.243.23.21", 6667); // irc.lfnet.org
if (!fTOR)
{
//struct hostent* phostent = gethostbyname("chat.freenode.net");
CAddress addrIRC("irc.lfnet.org", 6667, true);
if (addrIRC.IsValid())
addrConnect = addrIRC;
}
CService addrConnect("92.243.23.21", 6667); // irc.lfnet.org
CService addrIRC("irc.lfnet.org", 6667, true);
if (addrIRC.IsValid())
addrConnect = addrIRC;
SOCKET hSocket;
if (!ConnectSocket(addrConnect, hSocket))
@@ -330,15 +278,15 @@ void ThreadIRCSeed2(void* parg)
Sleep(500);
// Get our external IP from the IRC server and re-nick before joining the channel
CAddress addrFromIRC;
if (GetIPFromIRC(hSocket, strMyName, addrFromIRC.ip))
CNetAddr addrFromIRC;
if (GetIPFromIRC(hSocket, strMyName, addrFromIRC))
{
printf("GetIPFromIRC() returned %s\n", addrFromIRC.ToStringIP().c_str());
printf("GetIPFromIRC() returned %s\n", addrFromIRC.ToString().c_str());
if (!fUseProxy && addrFromIRC.IsRoutable())
{
// IRC lets you to re-nick
fGotExternalIP = true;
addrLocalHost.ip = addrFromIRC.ip;
addrLocalHost.SetIP(addrFromIRC);
strMyName = EncodeAddress(addrLocalHost);
Send(hSocket, strprintf("NICK %s\r", strMyName.c_str()).c_str());
}
@@ -393,7 +341,7 @@ void ThreadIRCSeed2(void* parg)
if (DecodeAddress(pszName, addr))
{
addr.nTime = GetAdjustedTime();
if (AddAddress(addr, 51 * 60))
if (addrman.Add(addr, addrConnect, 51 * 60))
printf("IRC got new address: %s\n", addr.ToString().c_str());
nGotIRCAddresses++;
}
@@ -406,10 +354,6 @@ void ThreadIRCSeed2(void* parg)
closesocket(hSocket);
hSocket = INVALID_SOCKET;
// IRC usually blocks TOR, so only try once
if (fTOR)
return;
if (GetTime() - nStart > 20 * 60)
{
nErrorWait /= 3;

View File

@@ -1,11 +1,10 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2011 The Bitcoin developers
// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_IRC_H
#define BITCOIN_IRC_H
bool RecvLine(SOCKET hSocket, std::string& strLine);
void ThreadIRCSeed(void* parg);
extern int nGotIRCAddresses;

117
src/key.cpp Normal file
View File

@@ -0,0 +1,117 @@
// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
#include <openssl/ec.h>
#include <openssl/ecdsa.h>
// Generate a private key from just the secret parameter
int EC_KEY_regenerate_key(EC_KEY *eckey, BIGNUM *priv_key)
{
int ok = 0;
BN_CTX *ctx = NULL;
EC_POINT *pub_key = NULL;
if (!eckey) return 0;
const EC_GROUP *group = EC_KEY_get0_group(eckey);
if ((ctx = BN_CTX_new()) == NULL)
goto err;
pub_key = EC_POINT_new(group);
if (pub_key == NULL)
goto err;
if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, ctx))
goto err;
EC_KEY_set_private_key(eckey,priv_key);
EC_KEY_set_public_key(eckey,pub_key);
ok = 1;
err:
if (pub_key)
EC_POINT_free(pub_key);
if (ctx != NULL)
BN_CTX_free(ctx);
return(ok);
}
// Perform ECDSA key recovery (see SEC1 4.1.6) for curves over (mod p)-fields
// recid selects which key is recovered
// if check is nonzero, additional checks are performed
int ECDSA_SIG_recover_key_GFp(EC_KEY *eckey, ECDSA_SIG *ecsig, const unsigned char *msg, int msglen, int recid, int check)
{
if (!eckey) return 0;
int ret = 0;
BN_CTX *ctx = NULL;
BIGNUM *x = NULL;
BIGNUM *e = NULL;
BIGNUM *order = NULL;
BIGNUM *sor = NULL;
BIGNUM *eor = NULL;
BIGNUM *field = NULL;
EC_POINT *R = NULL;
EC_POINT *O = NULL;
EC_POINT *Q = NULL;
BIGNUM *rr = NULL;
BIGNUM *zero = NULL;
int n = 0;
int i = recid / 2;
const EC_GROUP *group = EC_KEY_get0_group(eckey);
if ((ctx = BN_CTX_new()) == NULL) { ret = -1; goto err; }
BN_CTX_start(ctx);
order = BN_CTX_get(ctx);
if (!EC_GROUP_get_order(group, order, ctx)) { ret = -2; goto err; }
x = BN_CTX_get(ctx);
if (!BN_copy(x, order)) { ret=-1; goto err; }
if (!BN_mul_word(x, i)) { ret=-1; goto err; }
if (!BN_add(x, x, ecsig->r)) { ret=-1; goto err; }
field = BN_CTX_get(ctx);
if (!EC_GROUP_get_curve_GFp(group, field, NULL, NULL, ctx)) { ret=-2; goto err; }
if (BN_cmp(x, field) >= 0) { ret=0; goto err; }
if ((R = EC_POINT_new(group)) == NULL) { ret = -2; goto err; }
if (!EC_POINT_set_compressed_coordinates_GFp(group, R, x, recid % 2, ctx)) { ret=0; goto err; }
if (check)
{
if ((O = EC_POINT_new(group)) == NULL) { ret = -2; goto err; }
if (!EC_POINT_mul(group, O, NULL, R, order, ctx)) { ret=-2; goto err; }
if (!EC_POINT_is_at_infinity(group, O)) { ret = 0; goto err; }
}
if ((Q = EC_POINT_new(group)) == NULL) { ret = -2; goto err; }
n = EC_GROUP_get_degree(group);
e = BN_CTX_get(ctx);
if (!BN_bin2bn(msg, msglen, e)) { ret=-1; goto err; }
if (8*msglen > n) BN_rshift(e, e, 8-(n & 7));
zero = BN_CTX_get(ctx);
if (!BN_zero(zero)) { ret=-1; goto err; }
if (!BN_mod_sub(e, zero, e, order, ctx)) { ret=-1; goto err; }
rr = BN_CTX_get(ctx);
if (!BN_mod_inverse(rr, ecsig->r, order, ctx)) { ret=-1; goto err; }
sor = BN_CTX_get(ctx);
if (!BN_mod_mul(sor, ecsig->s, rr, order, ctx)) { ret=-1; goto err; }
eor = BN_CTX_get(ctx);
if (!BN_mod_mul(eor, e, rr, order, ctx)) { ret=-1; goto err; }
if (!EC_POINT_mul(group, Q, eor, R, sor, ctx)) { ret=-2; goto err; }
if (!EC_KEY_set_public_key(eckey, Q)) { ret=-2; goto err; }
ret = 1;
err:
if (ctx) {
BN_CTX_end(ctx);
BN_CTX_free(ctx);
}
if (R != NULL) EC_POINT_free(R);
if (O != NULL) EC_POINT_free(O);
if (Q != NULL) EC_POINT_free(Q);
return ret;
}

200
src/key.h
View File

@@ -1,5 +1,5 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2011 The Bitcoin developers
// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_KEY_H
@@ -12,9 +12,8 @@
#include <openssl/ecdsa.h>
#include <openssl/obj_mac.h>
#include "serialize.h"
#include "allocators.h"
#include "uint256.h"
#include "base58.h"
// secp160k1
// const unsigned int PRIVATE_KEY_SIZE = 192;
@@ -39,116 +38,8 @@
// see www.keylength.com
// script supports up to 75 for single byte push
// Generate a private key from just the secret parameter
int static inline EC_KEY_regenerate_key(EC_KEY *eckey, BIGNUM *priv_key)
{
int ok = 0;
BN_CTX *ctx = NULL;
EC_POINT *pub_key = NULL;
if (!eckey) return 0;
const EC_GROUP *group = EC_KEY_get0_group(eckey);
if ((ctx = BN_CTX_new()) == NULL)
goto err;
pub_key = EC_POINT_new(group);
if (pub_key == NULL)
goto err;
if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, ctx))
goto err;
EC_KEY_set_private_key(eckey,priv_key);
EC_KEY_set_public_key(eckey,pub_key);
ok = 1;
err:
if (pub_key)
EC_POINT_free(pub_key);
if (ctx != NULL)
BN_CTX_free(ctx);
return(ok);
}
// Perform ECDSA key recovery (see SEC1 4.1.6) for curves over (mod p)-fields
// recid selects which key is recovered
// if check is nonzero, additional checks are performed
int static inline ECDSA_SIG_recover_key_GFp(EC_KEY *eckey, ECDSA_SIG *ecsig, const unsigned char *msg, int msglen, int recid, int check)
{
if (!eckey) return 0;
int ret = 0;
BN_CTX *ctx = NULL;
BIGNUM *x = NULL;
BIGNUM *e = NULL;
BIGNUM *order = NULL;
BIGNUM *sor = NULL;
BIGNUM *eor = NULL;
BIGNUM *field = NULL;
EC_POINT *R = NULL;
EC_POINT *O = NULL;
EC_POINT *Q = NULL;
BIGNUM *rr = NULL;
BIGNUM *zero = NULL;
int n = 0;
int i = recid / 2;
const EC_GROUP *group = EC_KEY_get0_group(eckey);
if ((ctx = BN_CTX_new()) == NULL) { ret = -1; goto err; }
BN_CTX_start(ctx);
order = BN_CTX_get(ctx);
if (!EC_GROUP_get_order(group, order, ctx)) { ret = -2; goto err; }
x = BN_CTX_get(ctx);
if (!BN_copy(x, order)) { ret=-1; goto err; }
if (!BN_mul_word(x, i)) { ret=-1; goto err; }
if (!BN_add(x, x, ecsig->r)) { ret=-1; goto err; }
field = BN_CTX_get(ctx);
if (!EC_GROUP_get_curve_GFp(group, field, NULL, NULL, ctx)) { ret=-2; goto err; }
if (BN_cmp(x, field) >= 0) { ret=0; goto err; }
if ((R = EC_POINT_new(group)) == NULL) { ret = -2; goto err; }
if (!EC_POINT_set_compressed_coordinates_GFp(group, R, x, recid % 2, ctx)) { ret=0; goto err; }
if (check)
{
if ((O = EC_POINT_new(group)) == NULL) { ret = -2; goto err; }
if (!EC_POINT_mul(group, O, NULL, R, order, ctx)) { ret=-2; goto err; }
if (!EC_POINT_is_at_infinity(group, O)) { ret = 0; goto err; }
}
if ((Q = EC_POINT_new(group)) == NULL) { ret = -2; goto err; }
n = EC_GROUP_get_degree(group);
e = BN_CTX_get(ctx);
if (!BN_bin2bn(msg, msglen, e)) { ret=-1; goto err; }
if (8*msglen > n) BN_rshift(e, e, 8-(n & 7));
zero = BN_CTX_get(ctx);
if (!BN_zero(zero)) { ret=-1; goto err; }
if (!BN_mod_sub(e, zero, e, order, ctx)) { ret=-1; goto err; }
rr = BN_CTX_get(ctx);
if (!BN_mod_inverse(rr, ecsig->r, order, ctx)) { ret=-1; goto err; }
sor = BN_CTX_get(ctx);
if (!BN_mod_mul(sor, ecsig->s, rr, order, ctx)) { ret=-1; goto err; }
eor = BN_CTX_get(ctx);
if (!BN_mod_mul(eor, e, rr, order, ctx)) { ret=-1; goto err; }
if (!EC_POINT_mul(group, Q, eor, R, sor, ctx)) { ret=-2; goto err; }
if (!EC_KEY_set_public_key(eckey, Q)) { ret=-2; goto err; }
ret = 1;
err:
if (ctx) {
BN_CTX_end(ctx);
BN_CTX_free(ctx);
}
if (R != NULL) EC_POINT_free(R);
if (O != NULL) EC_POINT_free(O);
if (Q != NULL) EC_POINT_free(Q);
return ret;
}
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
{
@@ -163,21 +54,36 @@ typedef std::vector<unsigned char, secure_allocator<unsigned char> > CPrivKey;
// CSecret is a serialization of just the secret parameter (32 bytes)
typedef std::vector<unsigned char, secure_allocator<unsigned char> > CSecret;
/** An encapsulated OpenSSL Elliptic Curve key (public and/or private) */
class CKey
{
protected:
EC_KEY* pkey;
bool fSet;
bool fCompressedPubKey;
void SetCompressedPubKey()
{
EC_KEY_set_conv_form(pkey, POINT_CONVERSION_COMPRESSED);
fCompressedPubKey = true;
}
public:
CKey()
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;
}
CKey()
{
Reset();
}
CKey(const CKey& b)
{
pkey = EC_KEY_dup(b.pkey);
@@ -204,10 +110,17 @@ public:
return !fSet;
}
void MakeNewKey()
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;
}
@@ -220,7 +133,7 @@ public:
return true;
}
bool SetSecret(const CSecret& vchSecret)
bool SetSecret(const CSecret& vchSecret, bool fCompressed = false)
{
EC_KEY_free(pkey);
pkey = EC_KEY_new_by_curve_name(NID_secp256k1);
@@ -229,16 +142,21 @@ public:
if (vchSecret.size() != 32)
throw key_error("CKey::SetSecret() : secret must be 32 bytes");
BIGNUM *bn = BN_bin2bn(&vchSecret[0],32,BN_new());
if (bn == NULL)
if (bn == NULL)
throw key_error("CKey::SetSecret() : BN_bin2bn failed");
if (!EC_KEY_regenerate_key(pkey,bn))
{
BN_clear_free(bn);
throw key_error("CKey::SetSecret() : EC_KEY_regenerate_key failed");
}
BN_clear_free(bn);
fSet = true;
if (fCompressed || fCompressedPubKey)
SetCompressedPubKey();
return true;
}
CSecret GetSecret() const
CSecret GetSecret(bool &fCompressed) const
{
CSecret vchRet;
vchRet.resize(32);
@@ -249,12 +167,13 @@ public:
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
{
unsigned int nSize = i2d_ECPrivateKey(pkey, NULL);
int nSize = i2d_ECPrivateKey(pkey, NULL);
if (!nSize)
throw key_error("CKey::GetPrivKey() : i2d_ECPrivateKey failed");
CPrivKey vchPrivKey(nSize, 0);
@@ -270,12 +189,14 @@ public:
if (!o2i_ECPublicKey(&pkey, &pbegin, vchPubKey.size()))
return false;
fSet = true;
if (vchPubKey.size() == 33)
SetCompressedPubKey();
return true;
}
std::vector<unsigned char> GetPubKey() const
{
unsigned int nSize = i2o_ECPublicKey(pkey, NULL);
int nSize = i2o_ECPublicKey(pkey, NULL);
if (!nSize)
throw key_error("CKey::GetPubKey() : i2o_ECPublicKey failed");
std::vector<unsigned char> vchPubKey(nSize, 0);
@@ -287,13 +208,14 @@ public:
bool Sign(uint256 hash, std::vector<unsigned char>& vchSig)
{
vchSig.clear();
unsigned char pchSig[10000];
unsigned int nSize = 0;
if (!ECDSA_sign(0, (unsigned char*)&hash, sizeof(hash), pchSig, &nSize, pkey))
unsigned int nSize = ECDSA_size(pkey);
vchSig.resize(nSize); // Make sure it is big enough
if (!ECDSA_sign(0, (unsigned char*)&hash, sizeof(hash), &vchSig[0], &nSize, pkey))
{
vchSig.clear();
return false;
vchSig.resize(nSize);
memcpy(&vchSig[0], pchSig, nSize);
}
vchSig.resize(nSize); // Shrink to fit actual size
return true;
}
@@ -318,6 +240,8 @@ public:
{
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())
{
@@ -329,7 +253,7 @@ public:
if (nRecId == -1)
throw key_error("CKey::SignCompact() : unable to construct recoverable key");
vchSig[0] = nRecId+27;
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;
@@ -346,7 +270,8 @@ public:
{
if (vchSig.size() != 65)
return false;
if (vchSig[0]<27 || vchSig[0]>=31)
int nV = vchSig[0];
if (nV<27 || nV>=35)
return false;
ECDSA_SIG *sig = ECDSA_SIG_new();
BN_bin2bn(&vchSig[1],32,sig->r);
@@ -354,7 +279,12 @@ public:
EC_KEY_free(pkey);
pkey = EC_KEY_new_by_curve_name(NID_secp256k1);
if (ECDSA_SIG_recover_key_GFp(pkey, sig, (unsigned char*)&hash, sizeof(hash), vchSig[0] - 27, 0) == 1)
if (nV >= 31)
{
SetCompressedPubKey();
nV -= 4;
}
if (ECDSA_SIG_recover_key_GFp(pkey, sig, (unsigned char*)&hash, sizeof(hash), nV - 27, 0) == 1)
{
fSet = true;
ECDSA_SIG_free(sig);
@@ -382,10 +312,16 @@ public:
return true;
}
// Get the address corresponding to this key
CBitcoinAddress GetAddress() const
bool IsValid()
{
return CBitcoinAddress(GetPubKey());
if (!fSet)
return false;
bool fCompr;
CSecret secret = GetSecret(fCompr);
CKey key2;
key2.SetSecret(secret, fCompr);
return GetPubKey() == key2.GetPubKey();
}
};

View File

@@ -1,21 +1,10 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2011 The Bitcoin developers
// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
#include "headers.h"
#include "db.h"
#include "crypter.h"
std::vector<unsigned char> CKeyStore::GenerateNewKey()
{
RandAddSeedPerfmon();
CKey key;
key.MakeNewKey();
if (!AddKey(key))
throw std::runtime_error("CKeyStore::GenerateNewKey() : AddKey failed");
return key.GetPubKey();
}
#include "keystore.h"
#include "script.h"
bool CKeyStore::GetPubKey(const CBitcoinAddress &address, std::vector<unsigned char> &vchPubKeyOut) const
{
@@ -28,15 +17,53 @@ bool CKeyStore::GetPubKey(const CBitcoinAddress &address, std::vector<unsigned c
bool CBasicKeyStore::AddKey(const CKey& key)
{
CRITICAL_BLOCK(cs_KeyStore)
mapKeys[key.GetAddress()] = key.GetSecret();
bool fCompressed = false;
CSecret secret = key.GetSecret(fCompressed);
{
LOCK(cs_KeyStore);
mapKeys[CBitcoinAddress(key.GetPubKey())] = make_pair(secret, fCompressed);
}
return true;
}
bool CBasicKeyStore::AddCScript(const CScript& redeemScript)
{
{
LOCK(cs_KeyStore);
mapScripts[Hash160(redeemScript)] = redeemScript;
}
return true;
}
bool CBasicKeyStore::HaveCScript(const uint160& hash) const
{
bool result;
{
LOCK(cs_KeyStore);
result = (mapScripts.count(hash) > 0);
}
return result;
}
bool CBasicKeyStore::GetCScript(const uint160 &hash, CScript& redeemScriptOut) const
{
{
LOCK(cs_KeyStore);
ScriptMap::const_iterator mi = mapScripts.find(hash);
if (mi != mapScripts.end())
{
redeemScriptOut = (*mi).second;
return true;
}
}
return false;
}
bool CCryptoKeyStore::SetCrypted()
{
CRITICAL_BLOCK(cs_KeyStore)
{
LOCK(cs_KeyStore);
if (fUseCrypto)
return true;
if (!mapKeys.empty())
@@ -46,20 +73,10 @@ bool CCryptoKeyStore::SetCrypted()
return true;
}
std::vector<unsigned char> CCryptoKeyStore::GenerateNewKey()
{
RandAddSeedPerfmon();
CKey key;
key.MakeNewKey();
if (!AddKey(key))
throw std::runtime_error("CCryptoKeyStore::GenerateNewKey() : AddKey failed");
return key.GetPubKey();
}
bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn)
{
CRITICAL_BLOCK(cs_KeyStore)
{
LOCK(cs_KeyStore);
if (!SetCrypted())
return false;
@@ -71,7 +88,10 @@ bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn)
CSecret vchSecret;
if(!DecryptSecret(vMasterKeyIn, vchCryptedSecret, Hash(vchPubKey.begin(), vchPubKey.end()), vchSecret))
return false;
if (vchSecret.size() != 32)
return false;
CKey key;
key.SetPubKey(vchPubKey);
key.SetSecret(vchSecret);
if (key.GetPubKey() == vchPubKey)
break;
@@ -84,8 +104,8 @@ bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn)
bool CCryptoKeyStore::AddKey(const CKey& key)
{
CRITICAL_BLOCK(cs_KeyStore)
{
LOCK(cs_KeyStore);
if (!IsCrypted())
return CBasicKeyStore::AddKey(key);
@@ -94,7 +114,8 @@ bool CCryptoKeyStore::AddKey(const CKey& key)
std::vector<unsigned char> vchCryptedSecret;
std::vector<unsigned char> vchPubKey = key.GetPubKey();
if (!EncryptSecret(vMasterKey, key.GetSecret(), Hash(vchPubKey.begin(), vchPubKey.end()), vchCryptedSecret))
bool fCompressed;
if (!EncryptSecret(vMasterKey, key.GetSecret(fCompressed), Hash(vchPubKey.begin(), vchPubKey.end()), vchCryptedSecret))
return false;
if (!AddCryptedKey(key.GetPubKey(), vchCryptedSecret))
@@ -106,8 +127,8 @@ bool CCryptoKeyStore::AddKey(const CKey& key)
bool CCryptoKeyStore::AddCryptedKey(const std::vector<unsigned char> &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret)
{
CRITICAL_BLOCK(cs_KeyStore)
{
LOCK(cs_KeyStore);
if (!SetCrypted())
return false;
@@ -118,8 +139,8 @@ bool CCryptoKeyStore::AddCryptedKey(const std::vector<unsigned char> &vchPubKey,
bool CCryptoKeyStore::GetKey(const CBitcoinAddress &address, CKey& keyOut) const
{
CRITICAL_BLOCK(cs_KeyStore)
{
LOCK(cs_KeyStore);
if (!IsCrypted())
return CBasicKeyStore::GetKey(address, keyOut);
@@ -131,6 +152,9 @@ bool CCryptoKeyStore::GetKey(const CBitcoinAddress &address, CKey& keyOut) const
CSecret vchSecret;
if (!DecryptSecret(vMasterKey, vchCryptedSecret, Hash(vchPubKey.begin(), vchPubKey.end()), vchSecret))
return false;
if (vchSecret.size() != 32)
return false;
keyOut.SetPubKey(vchPubKey);
keyOut.SetSecret(vchSecret);
return true;
}
@@ -140,8 +164,8 @@ bool CCryptoKeyStore::GetKey(const CBitcoinAddress &address, CKey& keyOut) const
bool CCryptoKeyStore::GetPubKey(const CBitcoinAddress &address, std::vector<unsigned char>& vchPubKeyOut) const
{
CRITICAL_BLOCK(cs_KeyStore)
{
LOCK(cs_KeyStore);
if (!IsCrypted())
return CKeyStore::GetPubKey(address, vchPubKeyOut);
@@ -157,20 +181,21 @@ bool CCryptoKeyStore::GetPubKey(const CBitcoinAddress &address, std::vector<unsi
bool CCryptoKeyStore::EncryptKeys(CKeyingMaterial& vMasterKeyIn)
{
CRITICAL_BLOCK(cs_KeyStore)
{
LOCK(cs_KeyStore);
if (!mapCryptedKeys.empty() || IsCrypted())
return false;
fUseCrypto = true;
CKey key;
BOOST_FOREACH(KeyMap::value_type& mKey, mapKeys)
{
if (!key.SetSecret(mKey.second))
CKey key;
if (!key.SetSecret(mKey.second.first, mKey.second.second))
return false;
const std::vector<unsigned char> vchPubKey = key.GetPubKey();
std::vector<unsigned char> vchCryptedSecret;
if (!EncryptSecret(vMasterKeyIn, key.GetSecret(), Hash(vchPubKey.begin(), vchPubKey.end()), vchCryptedSecret))
bool fCompressed;
if (!EncryptSecret(vMasterKeyIn, key.GetSecret(fCompressed), Hash(vchPubKey.begin(), vchPubKey.end()), vchCryptedSecret))
return false;
if (!AddCryptedKey(vchPubKey, vchCryptedSecret))
return false;

View File

@@ -1,73 +1,107 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2011 The Bitcoin developers
// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_KEYSTORE_H
#define BITCOIN_KEYSTORE_H
#include "crypter.h"
#include "util.h"
#include "base58.h"
// A virtual base class for key stores
class CScript;
/** A virtual base class for key stores */
class CKeyStore
{
protected:
mutable CCriticalSection cs_KeyStore;
public:
virtual ~CKeyStore() {}
// Add a key to the store.
virtual bool AddKey(const CKey& key) =0;
// Check whether a key corresponding to a given address is present in the store.
virtual bool HaveKey(const CBitcoinAddress &address) const =0;
// Retrieve a key corresponding to a given address from the store.
// Return true if succesful.
virtual bool GetKey(const CBitcoinAddress &address, CKey& keyOut) const =0;
// Retrieve only the public key corresponding to a given address.
// This may succeed even if GetKey fails (e.g., encrypted wallets)
virtual void GetKeys(std::set<CBitcoinAddress> &setAddress) const =0;
virtual bool GetPubKey(const CBitcoinAddress &address, std::vector<unsigned char>& vchPubKeyOut) const;
// Generate a new key, and add it to the store
virtual std::vector<unsigned char> GenerateNewKey();
// Support for BIP 0013 : see https://en.bitcoin.it/wiki/BIP_0013
virtual bool AddCScript(const CScript& redeemScript) =0;
virtual bool HaveCScript(const uint160 &hash) const =0;
virtual bool GetCScript(const uint160 &hash, CScript& redeemScriptOut) const =0;
virtual bool GetSecret(const CBitcoinAddress &address, CSecret& vchSecret, bool &fCompressed) const
{
CKey key;
if (!GetKey(address, key))
return false;
vchSecret = key.GetSecret(fCompressed);
return true;
}
};
typedef std::map<CBitcoinAddress, CSecret> KeyMap;
typedef std::map<CBitcoinAddress, std::pair<CSecret, bool> > KeyMap;
typedef std::map<uint160, CScript > ScriptMap;
// Basic key store, that keeps keys in an address->secret map
/** Basic key store, that keeps keys in an address->secret map */
class CBasicKeyStore : public CKeyStore
{
protected:
KeyMap mapKeys;
ScriptMap mapScripts;
public:
bool AddKey(const CKey& key);
bool HaveKey(const CBitcoinAddress &address) const
{
bool result;
CRITICAL_BLOCK(cs_KeyStore)
{
LOCK(cs_KeyStore);
result = (mapKeys.count(address) > 0);
}
return result;
}
bool GetKey(const CBitcoinAddress &address, CKey& keyOut) const
void GetKeys(std::set<CBitcoinAddress> &setAddress) const
{
CRITICAL_BLOCK(cs_KeyStore)
setAddress.clear();
{
LOCK(cs_KeyStore);
KeyMap::const_iterator mi = mapKeys.begin();
while (mi != mapKeys.end())
{
setAddress.insert((*mi).first);
mi++;
}
}
}
bool GetKey(const CBitcoinAddress &address, CKey &keyOut) const
{
{
LOCK(cs_KeyStore);
KeyMap::const_iterator mi = mapKeys.find(address);
if (mi != mapKeys.end())
{
keyOut.SetSecret((*mi).second);
keyOut.Reset();
keyOut.SetSecret((*mi).second.first, (*mi).second.second);
return true;
}
}
return false;
}
virtual bool AddCScript(const CScript& redeemScript);
virtual bool HaveCScript(const uint160 &hash) const;
virtual bool GetCScript(const uint160 &hash, CScript& redeemScriptOut) const;
};
typedef std::map<CBitcoinAddress, std::pair<std::vector<unsigned char>, std::vector<unsigned char> > > CryptedKeyMap;
// Keystore which keeps the private keys encrypted
// It derives from the basic key store, which is used if no encryption is active.
/** Keystore which keeps the private keys encrypted.
* It derives from the basic key store, which is used if no encryption is active.
*/
class CCryptoKeyStore : public CBasicKeyStore
{
private:
@@ -102,8 +136,10 @@ public:
if (!IsCrypted())
return false;
bool result;
CRITICAL_BLOCK(cs_KeyStore)
{
LOCK(cs_KeyStore);
result = vMasterKey.empty();
}
return result;
}
@@ -112,19 +148,20 @@ public:
if (!SetCrypted())
return false;
CRITICAL_BLOCK(cs_KeyStore)
{
LOCK(cs_KeyStore);
vMasterKey.clear();
}
return true;
}
virtual bool AddCryptedKey(const std::vector<unsigned char> &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret);
std::vector<unsigned char> GenerateNewKey();
bool AddKey(const CKey& key);
bool HaveKey(const CBitcoinAddress &address) const
{
CRITICAL_BLOCK(cs_KeyStore)
{
LOCK(cs_KeyStore);
if (!IsCrypted())
return CBasicKeyStore::HaveKey(address);
return mapCryptedKeys.count(address) > 0;
@@ -133,6 +170,21 @@ public:
}
bool GetKey(const CBitcoinAddress &address, CKey& keyOut) const;
bool GetPubKey(const CBitcoinAddress &address, std::vector<unsigned char>& vchPubKeyOut) const;
void GetKeys(std::set<CBitcoinAddress> &setAddress) const
{
if (!IsCrypted())
{
CBasicKeyStore::GetKeys(setAddress);
return;
}
setAddress.clear();
CryptedKeyMap::const_iterator mi = mapCryptedKeys.begin();
while (mi != mapCryptedKeys.end())
{
setAddress.insert((*mi).first);
mi++;
}
}
};
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2011 The Bitcoin developers
// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_MAIN_H
@@ -7,31 +7,29 @@
#include "bignum.h"
#include "net.h"
#include "key.h"
#include "script.h"
#include "db.h"
#ifdef WIN32
#include <io.h> /* for _commit */
#endif
#include <list>
class CWallet;
class CBlock;
class CBlockIndex;
class CWalletTx;
class CWallet;
class CKeyItem;
class CReserveKey;
class CWalletDB;
class CAddress;
class CInv;
class CRequestTracker;
class CNode;
class CBlockIndex;
static const unsigned int MAX_BLOCK_SIZE = 1000000;
static const unsigned int MAX_BLOCK_SIZE_GEN = MAX_BLOCK_SIZE/2;
static const int MAX_BLOCK_SIGOPS = MAX_BLOCK_SIZE/50;
static const int64 COIN = 100000000;
static const int64 CENT = 1000000;
static const unsigned int MAX_BLOCK_SIGOPS = MAX_BLOCK_SIZE/50;
static const unsigned int MAX_ORPHAN_TRANSACTIONS = MAX_BLOCK_SIZE/100;
static const int64 MIN_TX_FEE = 50000;
static const int64 MIN_RELAY_TX_FEE = 10000;
static const int64 MAX_MONEY = 21000000 * COIN;
@@ -46,6 +44,9 @@ static const int fHaveUPnP = false;
#endif
extern CScript COINBASE_FLAGS;
@@ -60,6 +61,9 @@ extern CBigNum bnBestInvalidWork;
extern uint256 hashBestChain;
extern CBlockIndex* pindexBest;
extern unsigned int nTransactionsUpdated;
extern uint64 nLastBlockTx;
extern uint64 nLastBlockSize;
extern const std::string strMessageMagic;
extern double dHashesPerSec;
extern int64 nHPSTimerStart;
extern int64 nTimeBestReceived;
@@ -67,13 +71,7 @@ extern CCriticalSection cs_setpwalletRegistered;
extern std::set<CWallet*> setpwalletRegistered;
// Settings
extern int fGenerateBitcoins;
extern int64 nTransactionFee;
extern int fLimitProcessors;
extern int nLimitProcessors;
extern int fMinimizeToTray;
extern int fMinimizeOnClose;
extern int fUseUPnP;
@@ -117,21 +115,7 @@ std::string GetWarnings(std::string strFor);
bool GetWalletFile(CWallet* pwallet, std::string &strWalletFileOut);
template<typename T>
bool WriteSetting(const std::string& strKey, const T& value)
{
bool fOk = false;
BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered)
{
std::string strWalletFile;
if (!GetWalletFile(pwallet, strWalletFile))
continue;
fOk |= CWalletDB(strWalletFile).WriteSetting(strKey, value);
}
return fOk;
}
/** Position on disk for a particular transaction. */
class CDiskTxPos
{
public:
@@ -170,7 +154,7 @@ public:
std::string ToString() const
{
if (IsNull())
return strprintf("null");
return "null";
else
return strprintf("(nFile=%d, nBlockPos=%d, nTxPos=%d)", nFile, nBlockPos, nTxPos);
}
@@ -183,7 +167,7 @@ public:
/** An inpoint - a combination of a transaction and an index n into its vin */
class CInPoint
{
public:
@@ -198,7 +182,7 @@ public:
/** An outpoint - a combination of a transaction hash and an index n into its vout */
class COutPoint
{
public:
@@ -240,11 +224,10 @@ public:
//
// An input of a transaction. It contains the location of the previous
// transaction's output that it claims and a signature that matches the
// output's public key.
//
/** An input of a transaction. It contains the location of the previous
* transaction's output that it claims and a signature that matches the
* output's public key.
*/
class CTxIn
{
public:
@@ -254,17 +237,17 @@ public:
CTxIn()
{
nSequence = UINT_MAX;
nSequence = std::numeric_limits<unsigned int>::max();
}
explicit CTxIn(COutPoint prevoutIn, CScript scriptSigIn=CScript(), unsigned int nSequenceIn=UINT_MAX)
explicit CTxIn(COutPoint prevoutIn, CScript scriptSigIn=CScript(), unsigned int nSequenceIn=std::numeric_limits<unsigned int>::max())
{
prevout = prevoutIn;
scriptSig = scriptSigIn;
nSequence = nSequenceIn;
}
CTxIn(uint256 hashPrevTx, unsigned int nOut, CScript scriptSigIn=CScript(), unsigned int nSequenceIn=UINT_MAX)
CTxIn(uint256 hashPrevTx, unsigned int nOut, CScript scriptSigIn=CScript(), unsigned int nSequenceIn=std::numeric_limits<unsigned int>::max())
{
prevout = COutPoint(hashPrevTx, nOut);
scriptSig = scriptSigIn;
@@ -280,7 +263,7 @@ public:
bool IsFinal() const
{
return (nSequence == UINT_MAX);
return (nSequence == std::numeric_limits<unsigned int>::max());
}
friend bool operator==(const CTxIn& a, const CTxIn& b)
@@ -298,13 +281,13 @@ public:
std::string ToString() const
{
std::string str;
str += strprintf("CTxIn(");
str += "CTxIn(";
str += prevout.ToString();
if (prevout.IsNull())
str += strprintf(", coinbase %s", HexStr(scriptSig).c_str());
else
str += strprintf(", scriptSig=%s", scriptSig.ToString().substr(0,24).c_str());
if (nSequence != UINT_MAX)
if (nSequence != std::numeric_limits<unsigned int>::max())
str += strprintf(", nSequence=%u", nSequence);
str += ")";
return str;
@@ -319,10 +302,9 @@ public:
//
// An output of a transaction. It contains the public key that the next input
// must be able to sign with to claim it.
//
/** An output of a transaction. It contains the public key that the next input
* must be able to sign with to claim it.
*/
class CTxOut
{
public:
@@ -389,10 +371,18 @@ public:
//
// The basic transaction that is broadcasted on the network and contained in
// blocks. A transaction can contain multiple inputs and outputs.
//
enum GetMinFee_mode
{
GMF_BLOCK,
GMF_RELAY,
GMF_SEND,
};
typedef std::map<uint256, std::pair<CTxIndex, CTransaction> > MapPrevTx;
/** The basic transaction that is broadcasted on the network and contained in
* blocks. A transaction can contain multiple inputs and outputs.
*/
class CTransaction
{
public:
@@ -447,7 +437,7 @@ public:
nBlockHeight = nBestHeight;
if (nBlockTime == 0)
nBlockTime = GetAdjustedTime();
if ((int64)nLockTime < (nLockTime < LOCKTIME_THRESHOLD ? (int64)nBlockHeight : nBlockTime))
if ((int64)nLockTime < ((int64)nLockTime < LOCKTIME_THRESHOLD ? (int64)nBlockHeight : nBlockTime))
return true;
BOOST_FOREACH(const CTxIn& txin, vin)
if (!txin.IsFinal())
@@ -459,13 +449,13 @@ public:
{
if (vin.size() != old.vin.size())
return false;
for (int i = 0; i < vin.size(); i++)
for (unsigned int i = 0; i < vin.size(); i++)
if (vin[i].prevout != old.vin[i].prevout)
return false;
bool fNewer = false;
unsigned int nLowest = UINT_MAX;
for (int i = 0; i < vin.size(); i++)
unsigned int nLowest = std::numeric_limits<unsigned int>::max();
for (unsigned int i = 0; i < vin.size(); i++)
{
if (vin[i].nSequence != old.vin[i].nSequence)
{
@@ -489,27 +479,35 @@ public:
return (vin.size() == 1 && vin[0].prevout.IsNull());
}
int GetSigOpCount() const
{
int n = 0;
BOOST_FOREACH(const CTxIn& txin, vin)
n += txin.scriptSig.GetSigOpCount();
BOOST_FOREACH(const CTxOut& txout, vout)
n += txout.scriptPubKey.GetSigOpCount();
return n;
}
/** Check for standard transaction types
@return True if all outputs (scriptPubKeys) use only standard transaction forms
*/
bool IsStandard() const;
bool IsStandard() const
{
BOOST_FOREACH(const CTxIn& txin, vin)
if (!txin.scriptSig.IsPushOnly())
return error("nonstandard txin: %s", txin.scriptSig.ToString().c_str());
BOOST_FOREACH(const CTxOut& txout, vout)
if (!::IsStandard(txout.scriptPubKey))
return error("nonstandard txout: %s", txout.scriptPubKey.ToString().c_str());
return true;
}
/** Check for standard transaction types
@param[in] mapInputs Map of previous transactions that have outputs we're spending
@return True if all inputs (scriptSigs) use only standard transaction forms
@see CTransaction::FetchInputs
*/
bool AreInputsStandard(const MapPrevTx& mapInputs) const;
/** Count ECDSA signature operations the old-fashioned (pre-0.6) way
@return number of sigops this transaction's outputs will produce when spent
@see CTransaction::FetchInputs
*/
unsigned int GetLegacySigOpCount() const;
/** Count ECDSA signature operations in pay-to-script-hash inputs.
@param[in] mapInputs Map of previous transactions that have outputs we're spending
@return maximum number of sigops required to validate this transaction's inputs
@see CTransaction::FetchInputs
*/
unsigned int GetP2SHSigOpCount(const MapPrevTx& mapInputs) const;
/** Amount of bitcoins spent by this transaction.
@return sum of all outputs (note: does not include fees)
*/
int64 GetValueOut() const
{
int64 nValueOut = 0;
@@ -522,6 +520,16 @@ public:
return nValueOut;
}
/** Amount of bitcoins coming in to this transaction
Note that lightweight clients may not know anything besides the hash of previous transactions,
so may not be able to calculate this.
@param[in] mapInputs Map of previous transactions that have outputs we're spending
@return Sum of value of all inputs (scriptSigs)
@see CTransaction::FetchInputs
*/
int64 GetValueIn(const MapPrevTx& mapInputs) const;
static bool AllowFree(double dPriority)
{
// Large (in bytes) low-priority (new, small-coin) transactions
@@ -529,12 +537,12 @@ public:
return dPriority > COIN * 144 / 250;
}
int64 GetMinFee(unsigned int nBlockSize=1, bool fAllowFree=true, bool fForRelay=false) const
int64 GetMinFee(unsigned int nBlockSize=1, bool fAllowFree=true, enum GetMinFee_mode mode=GMF_BLOCK) const
{
// Base fee is either MIN_TX_FEE or MIN_RELAY_TX_FEE
int64 nBaseFee = fForRelay ? MIN_RELAY_TX_FEE : MIN_TX_FEE;
int64 nBaseFee = (mode == GMF_RELAY) ? MIN_RELAY_TX_FEE : MIN_TX_FEE;
unsigned int nBytes = ::GetSerializeSize(*this, SER_NETWORK);
unsigned int nBytes = ::GetSerializeSize(*this, SER_NETWORK, PROTOCOL_VERSION);
unsigned int nNewBlockSize = nBlockSize + nBytes;
int64 nMinFee = (1 + (int64)nBytes / 1000) * nBaseFee;
@@ -557,9 +565,11 @@ public:
// To limit dust spam, require MIN_TX_FEE/MIN_RELAY_TX_FEE if any output is less than 0.01
if (nMinFee < nBaseFee)
{
BOOST_FOREACH(const CTxOut& txout, vout)
if (txout.nValue < CENT)
nMinFee = nBaseFee;
}
// Raise the price as the block approaches full
if (nBlockSize != 1 && nNewBlockSize >= MAX_BLOCK_SIZE_GEN/2)
@@ -577,7 +587,7 @@ public:
bool ReadFromDisk(CDiskTxPos pos, FILE** pfileRet=NULL)
{
CAutoFile filein = OpenBlockFile(pos.nFile, 0, pfileRet ? "rb+" : "rb");
CAutoFile filein = CAutoFile(OpenBlockFile(pos.nFile, 0, pfileRet ? "rb+" : "rb"), SER_DISK, CLIENT_VERSION);
if (!filein)
return error("CTransaction::ReadFromDisk() : OpenBlockFile failed");
@@ -619,9 +629,9 @@ public:
vin.size(),
vout.size(),
nLockTime);
for (int i = 0; i < vin.size(); i++)
for (unsigned int i = 0; i < vin.size(); i++)
str += " " + vin[i].ToString() + "\n";
for (int i = 0; i < vout.size(); i++)
for (unsigned int i = 0; i < vout.size(); i++)
str += " " + vout[i].ToString() + "\n";
return str;
}
@@ -636,25 +646,48 @@ public:
bool ReadFromDisk(CTxDB& txdb, COutPoint prevout);
bool ReadFromDisk(COutPoint prevout);
bool DisconnectInputs(CTxDB& txdb);
bool ConnectInputs(CTxDB& txdb, std::map<uint256, CTxIndex>& mapTestPool, CDiskTxPos posThisTx,
CBlockIndex* pindexBlock, int64& nFees, bool fBlock, bool fMiner, int64 nMinFee=0);
/** Fetch from memory and/or disk. inputsRet keys are transaction hashes.
@param[in] txdb Transaction database
@param[in] mapTestPool List of pending changes to the transaction index database
@param[in] fBlock True if being called to add a new best-block to the chain
@param[in] fMiner True if being called by CreateNewBlock
@param[out] inputsRet Pointers to this transaction's inputs
@param[out] fInvalid returns true if transaction is invalid
@return Returns true if all inputs are in txdb or mapTestPool
*/
bool FetchInputs(CTxDB& txdb, const std::map<uint256, CTxIndex>& mapTestPool,
bool fBlock, bool fMiner, MapPrevTx& inputsRet, bool& fInvalid);
/** Sanity check previous transactions, then, if all checks succeed,
mark them as spent by this transaction.
@param[in] inputs Previous transactions (from FetchInputs)
@param[out] mapTestPool Keeps track of inputs that need to be updated on disk
@param[in] posThisTx Position of this transaction on disk
@param[in] pindexBlock
@param[in] fBlock true if called from ConnectBlock
@param[in] fMiner true if called from CreateNewBlock
@param[in] fStrictPayToScriptHash true if fully validating p2sh transactions
@return Returns true if all checks succeed
*/
bool ConnectInputs(MapPrevTx inputs,
std::map<uint256, CTxIndex>& mapTestPool, const CDiskTxPos& posThisTx,
const CBlockIndex* pindexBlock, bool fBlock, bool fMiner, bool fStrictPayToScriptHash=true);
bool ClientConnectInputs();
bool CheckTransaction() const;
bool AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs=true, bool* pfMissingInputs=NULL);
bool AcceptToMemoryPool(bool fCheckInputs=true, bool* pfMissingInputs=NULL);
protected:
bool AddToMemoryPoolUnchecked();
public:
bool RemoveFromMemoryPool();
const CTxOut& GetOutputFor(const CTxIn& input, const MapPrevTx& inputs) const;
};
//
// A transaction with a merkle branch linking it to the block chain
//
/** A transaction with a merkle branch linking it to the block chain. */
class CMerkleTx : public CTransaction
{
public:
@@ -663,7 +696,7 @@ public:
int nIndex;
// memory only
mutable char fMerkleVerified;
mutable bool fMerkleVerified;
CMerkleTx()
@@ -695,8 +728,8 @@ public:
int SetMerkleBranch(const CBlock* pblock=NULL);
int GetDepthInMainChain(int& nHeightRet) const;
int GetDepthInMainChain() const { int nHeight; return GetDepthInMainChain(nHeight); }
int GetDepthInMainChain(CBlockIndex* &pindexRet) const;
int GetDepthInMainChain() const { CBlockIndex *pindexRet; return GetDepthInMainChain(pindexRet); }
bool IsInMainChain() const { return GetDepthInMainChain() > 0; }
int GetBlocksToMaturity() const;
bool AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs=true);
@@ -706,11 +739,10 @@ public:
//
// A txdb record that contains the disk location of a transaction and the
// locations of transactions that spend its outputs. vSpent is really only
// used as a flag, but having the location is very helpful for debugging.
//
/** A txdb record that contains the disk location of a transaction and the
* locations of transactions that spend its outputs. vSpent is really only
* used as a flag, but having the location is very helpful for debugging.
*/
class CTxIndex
{
public:
@@ -758,23 +790,23 @@ public:
return !(a == b);
}
int GetDepthInMainChain() const;
};
//
// Nodes collect new transactions into a block, hash them into a hash tree,
// and scan through nonce values to make the block's hash satisfy proof-of-work
// requirements. When they solve the proof-of-work, they broadcast the block
// to everyone and the block is added to the block chain. The first transaction
// in the block is a special one that creates a new coin owned by the creator
// of the block.
//
// Blocks are appended to blk0001.dat files on disk. Their location on disk
// is indexed by CBlockIndex objects in memory.
//
/** Nodes collect new transactions into a block, hash them into a hash tree,
* and scan through nonce values to make the block's hash satisfy proof-of-work
* requirements. When they solve the proof-of-work, they broadcast the block
* to everyone and the block is added to the block chain. The first transaction
* in the block is a special one that creates a new coin owned by the creator
* of the block.
*
* Blocks are appended to blk0001.dat files on disk. Their location on disk
* is indexed by CBlockIndex objects in memory.
*/
class CBlock
{
public:
@@ -846,13 +878,7 @@ public:
return (int64)nTime;
}
int GetSigOpCount() const
{
int n = 0;
BOOST_FOREACH(const CTransaction& tx, vtx)
n += tx.GetSigOpCount();
return n;
}
void UpdateTime(const CBlockIndex* pindexPrev);
uint256 BuildMerkleTree() const
@@ -909,7 +935,7 @@ public:
bool WriteToDisk(unsigned int& nFileRet, unsigned int& nBlockPosRet)
{
// Open history file to append
CAutoFile fileout = AppendBlockFile(nFileRet);
CAutoFile fileout = CAutoFile(AppendBlockFile(nFileRet), SER_DISK, CLIENT_VERSION);
if (!fileout)
return error("CBlock::WriteToDisk() : AppendBlockFile failed");
@@ -918,9 +944,10 @@ public:
fileout << FLATDATA(pchMessageStart) << nSize;
// Write block
nBlockPosRet = ftell(fileout);
if (nBlockPosRet == -1)
long fileOutPos = ftell(fileout);
if (fileOutPos < 0)
return error("CBlock::WriteToDisk() : ftell failed");
nBlockPosRet = fileOutPos;
fileout << *this;
// Flush stdio buffers and commit to disk before returning
@@ -942,7 +969,7 @@ public:
SetNull();
// Open history file to read
CAutoFile filein = OpenBlockFile(nFile, nBlockPos, "rb");
CAutoFile filein = CAutoFile(OpenBlockFile(nFile, nBlockPos, "rb"), SER_DISK, CLIENT_VERSION);
if (!filein)
return error("CBlock::ReadFromDisk() : OpenBlockFile failed");
if (!fReadTransactions)
@@ -969,13 +996,13 @@ public:
hashMerkleRoot.ToString().substr(0,10).c_str(),
nTime, nBits, nNonce,
vtx.size());
for (int i = 0; i < vtx.size(); i++)
for (unsigned int i = 0; i < vtx.size(); i++)
{
printf(" ");
vtx[i].print();
}
printf(" vMerkleTree: ");
for (int i = 0; i < vMerkleTree.size(); i++)
for (unsigned int i = 0; i < vMerkleTree.size(); i++)
printf("%s ", vMerkleTree[i].ToString().substr(0,10).c_str());
printf("\n");
}
@@ -988,6 +1015,9 @@ public:
bool AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos);
bool CheckBlock() const;
bool AcceptBlock();
private:
bool SetBestChainInner(CTxDB& txdb, CBlockIndex *pindexNew);
};
@@ -995,14 +1025,13 @@ public:
//
// The block chain is a tree shaped structure starting with the
// genesis block at the root, with each block potentially having multiple
// candidates to be the next block. pprev and pnext link a path through the
// main/longest chain. A blockindex may have multiple pprev pointing back
// to it, but pnext will only point forward to the longest branch, or will
// be null if the block is not part of the longest chain.
//
/** The block chain is a tree shaped structure starting with the
* genesis block at the root, with each block potentially having multiple
* candidates to be the next block. pprev and pnext link a path through the
* main/longest chain. A blockindex may have multiple pprev pointing back
* to it, but pnext will only point forward to the longest branch, or will
* be null if the block is not part of the longest chain.
*/
class CBlockIndex
{
public:
@@ -1101,7 +1130,7 @@ public:
bool EraseBlockFromDisk()
{
// Open history file
CAutoFile fileout = OpenBlockFile(nFile, nBlockPos, "rb+");
CAutoFile fileout = CAutoFile(OpenBlockFile(nFile, nBlockPos, "rb+"), SER_DISK, CLIENT_VERSION);
if (!fileout)
return false;
@@ -1159,9 +1188,7 @@ public:
//
// Used to marshal pointers into hashes for db storage.
//
/** Used to marshal pointers into hashes for db storage. */
class CDiskBlockIndex : public CBlockIndex
{
public:
@@ -1236,11 +1263,10 @@ public:
//
// Describes a place in the block chain to another node such that if the
// other node doesn't have the same branch, it can find a recent common trunk.
// The further back it is, the further before the fork it may be.
//
/** Describes a place in the block chain to another node such that if the
* other node doesn't have the same branch, it can find a recent common trunk.
* The further back it is, the further before the fork it may be.
*/
class CBlockLocator
{
protected:
@@ -1263,6 +1289,11 @@ public:
Set((*mi).second);
}
CBlockLocator(const std::vector<uint256>& vHaveIn)
{
vHave = vHaveIn;
}
IMPLEMENT_SERIALIZE
(
if (!(nType & SER_GETHASH))
@@ -1367,13 +1398,12 @@ public:
//
// Alerts are for notifying old versions if they become too obsolete and
// need to upgrade. The message is displayed in the status bar.
// Alert messages are broadcast as a vector of signed data. Unserializing may
// not read the entire buffer if the alert is for a newer version, but older
// versions can still relay the original data.
//
/** Alerts are for notifying old versions if they become too obsolete and
* need to upgrade. The message is displayed in the status bar.
* Alert messages are broadcast as a vector of signed data. Unserializing may
* not read the entire buffer if the alert is for a newer version, but older
* versions can still relay the original data.
*/
class CUnsignedAlert
{
public:
@@ -1473,6 +1503,7 @@ public:
}
};
/** An alert is a combination of a serialized CUnsignedAlert and a signature. */
class CAlert : public CUnsignedAlert
{
public:
@@ -1521,6 +1552,7 @@ public:
bool AppliesTo(int nVersion, std::string strSubVerIn) const
{
// TODO: rework for client-version-embedded-in-strSubVer ?
return (IsInEffect() &&
nMinVer <= nVersion && nVersion <= nMaxVer &&
(setSubVer.empty() || setSubVer.count(strSubVerIn)));
@@ -1528,7 +1560,7 @@ public:
bool AppliesToMe() const
{
return AppliesTo(VERSION, ::pszSubVer);
return AppliesTo(PROTOCOL_VERSION, FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector<std::string>()));
}
bool RelayTo(CNode* pnode) const
@@ -1558,7 +1590,7 @@ public:
return error("CAlert::CheckSignature() : verify signature failed");
// Now unserialize the data
CDataStream sMsg(vchMsg);
CDataStream sMsg(vchMsg, SER_NETWORK, PROTOCOL_VERSION);
sMsg >> *(CUnsignedAlert*)this;
return true;
}
@@ -1566,4 +1598,35 @@ public:
bool ProcessAlert();
};
class CTxMemPool
{
public:
mutable CCriticalSection cs;
std::map<uint256, CTransaction> mapTx;
std::map<COutPoint, CInPoint> mapNextTx;
bool accept(CTxDB& txdb, CTransaction &tx,
bool fCheckInputs, bool* pfMissingInputs);
bool addUnchecked(CTransaction &tx);
bool remove(CTransaction &tx);
unsigned long size()
{
LOCK(cs);
return mapTx.size();
}
bool exists(uint256 hash)
{
return (mapTx.count(hash) != 0);
}
CTransaction& lookup(uint256 hash)
{
return mapTx[hash];
}
};
extern CTxMemPool mempool;
#endif

View File

@@ -9,13 +9,14 @@ USE_UPNP:=0
INCLUDEPATHS= \
-I"$(DEPSDIR)/boost_1_47_0" \
-I"$(DEPSDIR)/db-4.8.30.NC/build_unix" \
-I"$(DEPSDIR)/openssl-1.0.0e/include" \
-I"$(DEPSDIR)"
-I"$(DEPSDIR)/openssl-1.0.1b/include" \
-I"$(DEPSDIR)" \
-I"$(CURDIR)"/obj \
LIBPATHS= \
-L"$(DEPSDIR)/boost_1_47_0/stage/lib" \
-L"$(DEPSDIR)/db-4.8.30.NC/build_unix" \
-L"$(DEPSDIR)/openssl-1.0.0e"
-L"$(DEPSDIR)/openssl-1.0.1b"
LIBS= \
-l boost_system-mt-s \
@@ -26,32 +27,11 @@ LIBS= \
-l ssl \
-l crypto
DEFS=-D_MT -DWIN32 -D_WINDOWS -DNOPCH -DUSE_SSL -DBOOST_THREAD_USE_LIB
DEFS=-D_MT -DWIN32 -D_WINDOWS -DBOOST_THREAD_USE_LIB
DEBUGFLAGS=-g
CFLAGS=-O2 -w -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(DEFS) $(INCLUDEPATHS)
HEADERS = \
base58.h \
bignum.h \
checkpoints.h \
crypter.h \
db.h \
headers.h \
init.h \
irc.h \
key.h \
keystore.h \
main.h \
net.h \
noui.h \
protocol.h \
bitcoinrpc.h \
script.h \
serialize.h \
strlcpy.h \
uint256.h \
util.h \
wallet.h
TESTDEFS = -DTEST_DATA_DIR=$(abspath test/data)
ifdef USE_UPNP
LIBPATHS += -L"$(DEPSDIR)/miniupnpc"
@@ -61,9 +41,16 @@ endif
LIBS += -l mingwthrd -l kernel32 -l user32 -l gdi32 -l comdlg32 -l winspool -l winmm -l shell32 -l comctl32 -l ole32 -l oleaut32 -l uuid -l rpcrt4 -l advapi32 -l ws2_32 -l shlwapi
# TODO: make the mingw builds smarter about dependencies, like the linux/osx builds are
HEADERS = $(wildcard *.h)
OBJS= \
obj/version.o \
obj/checkpoints.o \
obj/netbase.o \
obj/addrman.o \
obj/crypter.o \
obj/key.o \
obj/db.o \
obj/init.o \
obj/irc.o \
@@ -72,31 +59,40 @@ OBJS= \
obj/net.o \
obj/protocol.o \
obj/bitcoinrpc.o \
obj/rpcdump.o \
obj/script.o \
obj/util.o \
obj/wallet.o
obj/wallet.o \
obj/walletdb.o \
obj/noui.o
all: bitcoind.exe
obj/nogui/%.o: %.cpp $(HEADERS)
obj/build.h: FORCE
../share/genbuild.sh obj/build.h
version.cpp: obj/build.h
DEFS += -DHAVE_BUILD_INFO
obj/%.o: %.cpp $(HEADERS)
i586-mingw32msvc-g++ -c $(CFLAGS) -o $@ $<
bitcoind.exe: $(OBJS:obj/%=obj/nogui/%)
bitcoind.exe: $(OBJS:obj/%=obj/%)
i586-mingw32msvc-g++ $(CFLAGS) -o $@ $(LIBPATHS) $^ $(LIBS)
TESTOBJS := $(patsubst test/%.cpp,obj-test/%.o,$(wildcard test/*.cpp))
obj/test/%.o: obj/test/%.cpp $(HEADERS)
i586-mingw32msvc-g++ -c $(CFLAGS) -o $@ $<
obj-test/%.o: test/%.cpp $(HEADERS)
i586-mingw32msvc-g++ -c $(TESTDEFS) $(CFLAGS) -o $@ $<
test_bitcoin.exe: obj/test/test_bitcoin.o $(filter-out obj/nogui/init.o,$(OBJS:obj/%=obj/nogui/%))
i586-mingw32msvc-g++ $(CFLAGS) -o $@ $(LIBPATHS) $^ $(LIBS) -lboost_unit_test_framework-mt-s
test_bitcoin.exe: $(TESTOBJS) $(filter-out obj/init.o,$(OBJS:obj/%=obj/%))
i586-mingw32msvc-g++ $(CFLAGS) -o $@ $(LIBPATHS) $^ -lboost_unit_test_framework $(LIBS)
clean:
-rm -f obj/*.o
-rm -f obj/nogui/*.o
-rm -f obj/test/*.o
-rm -f test/*.o
-rm -f headers.h.gch
-rm -f bitcoind.exe
-rm -f obj-test/*.o
-rm -f test_bitcoin.exe
-rm -f src/build.h
FORCE:

View File

@@ -23,31 +23,11 @@ LIBS= \
-l ssl \
-l crypto
DEFS=-DWIN32 -D_WINDOWS -DNOPCH -DUSE_SSL -DBOOST_THREAD_USE_LIB
DEFS=-DWIN32 -D_WINDOWS -DBOOST_THREAD_USE_LIB
DEBUGFLAGS=-g
CFLAGS=-mthreads -O2 -w -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(DEFS) $(INCLUDEPATHS)
HEADERS = \
base58.h \
bignum.h \
checkpoints.h \
crypter.h \
db.h \
headers.h \
init.h \
irc.h \
key.h \
keystore.h \
main.h \
net.h \
noui.h \
protocol.h \
bitcoinrpc.h \
script.h \
serialize.h \
strlcpy.h \
uint256.h \
util.h \
wallet.h
TESTDEFS = -DTEST_DATA_DIR=$(abspath test/data)
ifdef USE_UPNP
INCLUDEPATHS += -I"C:\miniupnpc-1.6-mgw"
@@ -58,9 +38,16 @@ endif
LIBS += -l kernel32 -l user32 -l gdi32 -l comdlg32 -l winspool -l winmm -l shell32 -l comctl32 -l ole32 -l oleaut32 -l uuid -l rpcrt4 -l advapi32 -l ws2_32 -l shlwapi
# TODO: make the mingw builds smarter about dependencies, like the linux/osx builds are
HEADERS = $(wildcard *.h)
OBJS= \
obj/version.o \
obj/checkpoints.o \
obj/netbase.o \
obj/addrman.o \
obj/crypter.o \
obj/key.o \
obj/db.o \
obj/init.o \
obj/irc.o \
@@ -69,29 +56,32 @@ OBJS= \
obj/net.o \
obj/protocol.o \
obj/bitcoinrpc.o \
obj/rpcdump.o \
obj/script.o \
obj/util.o \
obj/wallet.o
obj/wallet.o \
obj/walletdb.o \
obj/noui.o
all: bitcoind.exe
obj/nogui/%.o: %.cpp $(HEADERS)
obj/%.o: %.cpp $(HEADERS)
g++ -c $(CFLAGS) -o $@ $<
bitcoind.exe: $(OBJS:obj/%=obj/nogui/%)
bitcoind.exe: $(OBJS:obj/%=obj/%)
g++ $(CFLAGS) -o $@ $(LIBPATHS) $^ $(LIBS)
obj/test/test_bitcoin.o: $(wildcard test/*.cpp) $(HEADERS)
g++ -c $(CFLAGS) -o $@ test/test_bitcoin.cpp
TESTOBJS := $(patsubst test/%.cpp,obj-test/%.o,$(wildcard test/*.cpp))
test_bitcoin.exe: obj/test/test_bitcoin.o $(filter-out obj/nogui/init.o,$(OBJS:obj/%=obj/nogui/%))
g++ $(CFLAGS) -o $@ $(LIBPATHS) $^ $(LIBS)
obj-test/%.o: test/%.cpp $(HEADERS)
g++ -c $(TESTDEFS) $(CFLAGS) -o $@ $<
test_bitcoin.exe: $(TESTOBJS) $(filter-out obj/init.o,$(OBJS:obj/%=obj/%))
g++ $(CFLAGS) -o $@ $(LIBPATHS) $^ -lboost_unit_test_framework $(LIBS)
clean:
-del /Q bitcoind test_bitcoin
-del /Q obj\*
-del /Q obj\nogui\*
-del /Q obj\test\*
-del /Q test\*.o
-del /Q headers.h.gch
-del /Q obj-test\*
-del /Q build.h

View File

@@ -10,6 +10,8 @@ CXX=llvm-g++
DEPSDIR=/opt/local
INCLUDEPATHS= \
-I"$(CURDIR)" \
-I"$(CURDIR)"/obj \
-I"$(DEPSDIR)/include" \
-I"$(DEPSDIR)/include/db48"
@@ -20,8 +22,13 @@ LIBPATHS= \
USE_UPNP:=1
LIBS= -dead_strip
TESTDEFS = -DTEST_DATA_DIR=$(abspath test/data)
ifdef STATIC
# Build STATIC if you are redistributing the bitcoind binary
TESTLIBS += \
$(DEPSDIR)/lib/libboost_unit_test_framework-mt.a
LIBS += \
$(DEPSDIR)/lib/db48/libdb_cxx-4.8.a \
$(DEPSDIR)/lib/libboost_system-mt.a \
@@ -29,8 +36,11 @@ LIBS += \
$(DEPSDIR)/lib/libboost_program_options-mt.a \
$(DEPSDIR)/lib/libboost_thread-mt.a \
$(DEPSDIR)/lib/libssl.a \
$(DEPSDIR)/lib/libcrypto.a
$(DEPSDIR)/lib/libcrypto.a \
-lz
else
TESTLIBS += \
-lboost_unit_test_framework-mt
LIBS += \
-ldb_cxx-4.8 \
-lboost_system-mt \
@@ -38,40 +48,33 @@ LIBS += \
-lboost_program_options-mt \
-lboost_thread-mt \
-lssl \
-lcrypto
-lcrypto \
-lz
TESTDEFS += -DBOOST_TEST_DYN_LINK
endif
DEFS=-DMAC_OSX -DMSG_NOSIGNAL=0 -DUSE_SSL
DEFS=-DMAC_OSX -DMSG_NOSIGNAL=0
ifdef RELEASE
# Compile for maximum compatibility and smallest size.
# This requires that dependencies are compiled
# the same way.
CFLAGS = -mmacosx-version-min=10.5 -arch i386 -O3
else
CFLAGS = -g
endif
DEBUGFLAGS=-g
# ppc doesn't work because we don't support big-endian
CFLAGS=-mmacosx-version-min=10.5 -arch i386 -O3 -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(DEFS) $(INCLUDEPATHS)
HEADERS = \
base58.h \
bignum.h \
checkpoints.h \
crypter.h \
db.h \
headers.h \
init.h \
irc.h \
key.h \
keystore.h \
main.h \
net.h \
noui.h \
protocol.h \
bitcoinrpc.h \
script.h \
serialize.h \
strlcpy.h \
uint256.h \
util.h \
wallet.h
CFLAGS += -Wextra -Wno-sign-compare -Wno-invalid-offsetof -Wformat-security \
$(DEBUGFLAGS) $(DEFS) $(INCLUDEPATHS)
OBJS= \
obj/version.o \
obj/checkpoints.o \
obj/netbase.o \
obj/addrman.o \
obj/crypter.o \
obj/key.o \
obj/db.o \
obj/init.o \
obj/irc.o \
@@ -80,9 +83,12 @@ OBJS= \
obj/net.o \
obj/protocol.o \
obj/bitcoinrpc.o \
obj/rpcdump.o \
obj/script.o \
obj/util.o \
obj/wallet.o
obj/wallet.o \
obj/walletdb.o \
obj/noui.o
ifdef USE_UPNP
DEFS += -DUSE_UPNP=$(USE_UPNP)
@@ -93,38 +99,45 @@ else
endif
endif
all: bitcoind
# auto-generated dependencies:
-include obj/nogui/*.P
-include obj/test/*.P
-include obj/*.P
-include obj-test/*.P
obj/nogui/%.o: %.cpp
obj/build.h: FORCE
../share/genbuild.sh obj/build.h
version.cpp: obj/build.h
DEFS += -DHAVE_BUILD_INFO
obj/%.o: %.cpp
$(CXX) -c $(CFLAGS) -MMD -o $@ $<
@cp $(@:%.o=%.d) $(@:%.o=%.P); \
sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \
-e '/^$$/ d' -e 's/$$/ :/' < $(@:%.o=%.d) >> $(@:%.o=%.P); \
rm -f $(@:%.o=%.d)
bitcoind: $(OBJS:obj/%=obj/nogui/%)
bitcoind: $(OBJS:obj/%=obj/%)
$(CXX) $(CFLAGS) -o $@ $(LIBPATHS) $^ $(LIBS)
obj/test/%.o: test/%.cpp
$(CXX) -c $(CFLAGS) -MMD -o $@ $<
TESTOBJS := $(patsubst test/%.cpp,obj-test/%.o,$(wildcard test/*.cpp))
obj-test/%.o: test/%.cpp
$(CXX) -c $(TESTDEFS) $(CFLAGS) -MMD -o $@ $<
@cp $(@:%.o=%.d) $(@:%.o=%.P); \
sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \
-e '/^$$/ d' -e 's/$$/ :/' < $(@:%.o=%.d) >> $(@:%.o=%.P); \
rm -f $(@:%.o=%.d)
test_bitcoin: obj/test/test_bitcoin.o $(filter-out obj/nogui/init.o,$(OBJS:obj/%=obj/nogui/%))
$(CXX) $(CFLAGS) -o $@ $(LIBPATHS) $^ $(LIBS) $(DEPSDIR)/lib/libboost_unit_test_framework-mt.a
test_bitcoin: $(TESTOBJS) $(filter-out obj/init.o,$(OBJS:obj/%=obj/%))
$(CXX) $(CFLAGS) -o $@ $(LIBPATHS) $^ $(LIBS) $(TESTLIBS)
clean:
-rm -f bitcoind test_bitcoin
-rm -f obj/*.o
-rm -f obj/nogui/*.o
-rm -f obj/test/*.o
-rm -f obj-test/*.o
-rm -f obj/*.P
-rm -f obj/nogui/*.P
-rm -f obj/test/*.P
-rm -f obj-test/*.P
-rm -f src/build.h
FORCE:

View File

@@ -4,10 +4,12 @@
USE_UPNP:=0
DEFS=-DNOPCH
DEFS=
DEFS += $(addprefix -I,$(BOOST_INCLUDE_PATH) $(BDB_INCLUDE_PATH) $(OPENSSL_INCLUDE_PATH))
LIBS += $(addprefix -l,$(BOOST_LIB_PATH) $(BDB_LIB_PATH) $(OPENSSL_LIB_PATH))
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))
TESTDEFS = -DTEST_DATA_DIR=$(abspath test/data)
LMODE = dynamic
LMODE2 = dynamic
@@ -16,10 +18,12 @@ ifdef STATIC
ifeq (${STATIC}, all)
LMODE2 = static
endif
else
TESTDEFS += -DBOOST_TEST_DYN_LINK
endif
# for boost 1.37, add -mt to the boost libraries
LIBS= \
LIBS += \
-Wl,-B$(LMODE) \
-l boost_system$(BOOST_LIB_SUFFIX) \
-l boost_filesystem$(BOOST_LIB_SUFFIX) \
@@ -37,10 +41,6 @@ ifneq (${USE_UPNP}, -)
DEFS += -DUSE_UPNP=$(USE_UPNP)
endif
ifneq (${USE_SSL}, 0)
DEFS += -DUSE_SSL
endif
LIBS+= \
-Wl,-B$(LMODE2) \
-l z \
@@ -83,33 +83,16 @@ LIBS+= \
DEBUGFLAGS=-g
CXXFLAGS=-O2
xCXXFLAGS=-pthread -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(DEFS) $(HARDENING) $(CXXFLAGS)
HEADERS = \
base58.h \
bignum.h \
checkpoints.h \
crypter.h \
db.h \
headers.h \
init.h \
irc.h \
key.h \
keystore.h \
main.h \
net.h \
noui.h \
protocol.h \
bitcoinrpc.h \
script.h \
serialize.h \
strlcpy.h \
uint256.h \
util.h \
wallet.h
xCXXFLAGS=-pthread -Wall -Wextra -Wno-sign-compare -Wno-invalid-offsetof -Wno-unused-parameter -Wformat -Wformat-security \
$(DEBUGFLAGS) $(DEFS) $(HARDENING) $(CXXFLAGS)
OBJS= \
obj/version.o \
obj/checkpoints.o \
obj/netbase.o \
obj/addrman.o \
obj/crypter.o \
obj/key.o \
obj/db.o \
obj/init.o \
obj/irc.o \
@@ -118,42 +101,53 @@ OBJS= \
obj/net.o \
obj/protocol.o \
obj/bitcoinrpc.o \
obj/rpcdump.o \
obj/script.o \
obj/util.o \
obj/wallet.o
obj/wallet.o \
obj/walletdb.o \
obj/noui.o
all: bitcoind
# auto-generated dependencies:
-include obj/nogui/*.P
-include obj/test/*.P
-include obj/*.P
-include obj-test/*.P
obj/nogui/%.o: %.cpp
obj/build.h: FORCE
../share/genbuild.sh obj/build.h
version.cpp: obj/build.h
DEFS += -DHAVE_BUILD_INFO
obj/%.o: %.cpp
$(CXX) -c $(xCXXFLAGS) -MMD -o $@ $<
@cp $(@:%.o=%.d) $(@:%.o=%.P); \
sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \
-e '/^$$/ d' -e 's/$$/ :/' < $(@:%.o=%.d) >> $(@:%.o=%.P); \
rm -f $(@:%.o=%.d)
bitcoind: $(OBJS:obj/%=obj/nogui/%)
bitcoind: $(OBJS:obj/%=obj/%)
$(CXX) $(xCXXFLAGS) -o $@ $^ $(LDFLAGS) $(LIBS)
obj/test/%.o: test/%.cpp
$(CXX) -c $(xCXXFLAGS) -MMD -o $@ $<
TESTOBJS := $(patsubst test/%.cpp,obj-test/%.o,$(wildcard test/*.cpp))
obj-test/%.o: test/%.cpp
$(CXX) -c $(TESTDEFS) $(xCXXFLAGS) -MMD -o $@ $<
@cp $(@:%.o=%.d) $(@:%.o=%.P); \
sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \
-e '/^$$/ d' -e 's/$$/ :/' < $(@:%.o=%.d) >> $(@:%.o=%.P); \
rm -f $(@:%.o=%.d)
test_bitcoin: obj/test/test_bitcoin.o $(filter-out obj/nogui/init.o,$(OBJS:obj/%=obj/nogui/%))
$(CXX) $(xCXXFLAGS) -o $@ $(LIBPATHS) $^ -Wl,-Bstatic -lboost_unit_test_framework $(LDFLAGS) $(LIBS)
test_bitcoin: $(TESTOBJS) $(filter-out obj/init.o,$(OBJS:obj/%=obj/%))
$(CXX) $(xCXXFLAGS) -o $@ $(LIBPATHS) $^ -Wl,-B$(LMODE) -lboost_unit_test_framework $(LDFLAGS) $(LIBS)
clean:
-rm -f bitcoind test_bitcoin
-rm -f obj/*.o
-rm -f obj/nogui/*.o
-rm -f obj/test/*.o
-rm -f obj-test/*.o
-rm -f obj/*.P
-rm -f obj/nogui/*.P
-rm -f obj/test/*.P
-rm -f obj-test/*.P
-rm -f src/build.h
FORCE:

View File

@@ -1,153 +0,0 @@
# Copyright (c) 2009-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.
INCLUDEPATHS= \
/I"/boost" \
/I"/db/build_windows" \
/I"/openssl/include" \
/I"/miniupnpc"
LIBPATHS= \
/LIBPATH:"/boost/stage/lib" \
/LIBPATH:"/db/build_windows/Release" \
/LIBPATH:"/openssl/lib" \
/LIBPATH:"/miniupnpc/msvc/Release" \
/NODEFAULTLIB:libc.lib /NODEFAULTLIB:libcmt.lib \
/NODEFAULTLIB:libcd.lib /NODEFAULTLIB:libcmtd.lib \
/NODEFAULTLIB:msvcrtd.lib
USE_UPNP=0
DEFS=/DWIN32 /D_WINDOWS /DNOPCH /DNOMINMAX
LIBS= \
libboost_system-vc100-mt.lib \
libboost_filesystem-vc100-mt.lib \
libboost_program_options-vc100-mt.lib \
libboost_thread-vc100-mt.lib \
libdb47s.lib \
libeay32.lib
!IFDEF USE_UPNP
LIBS=$(LIBS) miniupnpc.lib
DEFS=$(DEFS) /DUSE_UPNP=$(USE_UPNP)
!ENDIF
LIBS=$(LIBS) \
kernel32.lib user32.lib gdi32.lib comdlg32.lib winspool.lib winmm.lib shell32.lib comctl32.lib ole32.lib oleaut32.lib uuid.lib rpcrt4.lib advapi32.lib ws2_32.lib shlwapi.lib iphlpapi.lib
DEBUGFLAGS=/Os
CFLAGS=/MD /c /nologo /EHsc /GR /Zm300 $(DEBUGFLAGS) $(DEFS) $(INCLUDEPATHS)
HEADERS = \
base58.h \
bignum.h \
checkpoints.h \
crypter.h \
db.h \
headers.h \
init.h \
irc.h \
key.h \
keystore.h \
main.h \
net.h \
noui.h \
protocol.h \
bitcoinrpc.h \
script.h \
serialize.h \
strlcpy.h \
ui.h \
uibase.h \
uint256.h \
util.h \
wallet.h
OBJS= \
obj\checkpoints.o \
obj\crypter.o \
obj\db.o \
obj\init.o \
obj\irc.o \
obj\keystore.o \
obj\main.o \
obj\net.o \
obj\rpc.o \
obj\protocol.o \
obj\script.o \
obj\util.o \
obj\wallet.o
RC=../share
all: bitcoind.exe
.cpp{obj}.obj:
cl $(CFLAGS) /DGUI /Fo$@ %s
obj\checkpoints.obj: $(HEADERS)
obj\util.obj: $(HEADERS)
obj\script.obj: $(HEADERS)
obj\db.obj: $(HEADERS)
obj\net.obj: $(HEADERS)
obj\irc.obj: $(HEADERS)
obj\keystore.obj: $(HEADERS)
obj\main.obj: $(HEADERS)
obj\wallet.obj: $(HEADERS)
obj\rpc.obj: $(HEADERS)
obj\init.obj: $(HEADERS)
obj\crypter.obj: $(HEADERS)
obj\ui.obj: $(HEADERS)
obj\uibase.obj: $(HEADERS)
.cpp{obj\nogui}.obj:
cl $(CFLAGS) /Fo$@ %s
obj\nogui\checkpoints.obj: $(HEADERS)
obj\nogui\util.obj: $(HEADERS)
obj\nogui\script.obj: $(HEADERS)
obj\nogui\db.obj: $(HEADERS)
obj\nogui\net.obj: $(HEADERS)
obj\nogui\irc.obj: $(HEADERS)
obj\nogui\keystore.obj: $(HEADERS)
obj\nogui\main.obj: $(HEADERS)
obj\nogui\wallet.obj: $(HEADERS)
obj\nogui\rpc.obj: $(HEADERS)
obj\nogui\init.obj: $(HEADERS)
bitcoind.exe: $(OBJS:obj\=obj\nogui\) obj\ui.res
link /nologo /OUT:$@ $(LIBPATHS) $** $(LIBS)
clean:
-del /Q obj\*
-del /Q obj\nogui\*
-del /Q *.ilk
-del /Q *.pdb
-del /Q bitcoind.exe

64
src/mruset.h Normal file
View File

@@ -0,0 +1,64 @@
// 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.
#ifndef BITCOIN_MRUSET_H
#define BITCOIN_MRUSET_H
#include <set>
#include <deque>
/** STL-like set container that only keeps the most recent N elements. */
template <typename T> class mruset
{
public:
typedef T key_type;
typedef T value_type;
typedef typename std::set<T>::iterator iterator;
typedef typename std::set<T>::const_iterator const_iterator;
typedef typename std::set<T>::size_type size_type;
protected:
std::set<T> set;
std::deque<T> queue;
size_type nMaxSize;
public:
mruset(size_type nMaxSizeIn = 0) { nMaxSize = nMaxSizeIn; }
iterator begin() const { return set.begin(); }
iterator end() const { return set.end(); }
size_type size() const { return set.size(); }
bool empty() const { return set.empty(); }
iterator find(const key_type& k) const { return set.find(k); }
size_type count(const key_type& k) const { return set.count(k); }
bool inline friend operator==(const mruset<T>& a, const mruset<T>& b) { return a.set == b.set; }
bool inline friend operator==(const mruset<T>& a, const std::set<T>& b) { return a.set == b; }
bool inline friend operator<(const mruset<T>& a, const mruset<T>& b) { return a.set < b.set; }
std::pair<iterator, bool> insert(const key_type& x)
{
std::pair<iterator, bool> ret = set.insert(x);
if (ret.second)
{
if (nMaxSize && queue.size() == nMaxSize)
{
set.erase(queue.front());
queue.pop_front();
}
queue.push_back(x);
}
return ret;
}
size_type max_size() const { return nMaxSize; }
size_type max_size(size_type s)
{
if (s)
while (queue.size() >= s)
{
set.erase(queue.front());
queue.pop_front();
}
nMaxSize = s;
return nMaxSize;
}
};
#endif

File diff suppressed because it is too large Load Diff

197
src/net.h
View File

@@ -1,5 +1,5 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2011 The Bitcoin developers
// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_NET_H
@@ -14,31 +14,28 @@
#include <arpa/inet.h>
#endif
#include "mruset.h"
#include "netbase.h"
#include "protocol.h"
#include "addrman.h"
class CAddrDB;
class CRequestTracker;
class CNode;
class CBlockIndex;
extern int nBestHeight;
extern int nConnectTimeout;
inline unsigned int ReceiveBufferSize() { return 1000*GetArg("-maxreceivebuffer", 10*1000); }
inline unsigned int SendBufferSize() { return 1000*GetArg("-maxsendbuffer", 10*1000); }
static const unsigned int PUBLISH_HOPS = 5;
bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet, int nTimeout=nConnectTimeout);
bool Lookup(const char *pszName, std::vector<CAddress>& vaddr, int nServices, int nMaxSolutions, bool fAllowLookup = false, int portDefault = 0, bool fAllowPort = false);
bool Lookup(const char *pszName, CAddress& addr, int nServices, bool fAllowLookup = false, int portDefault = 0, bool fAllowPort = false);
bool GetMyExternalIP(unsigned int& ipRet);
bool AddAddress(CAddress addr, int64 nTimePenalty=0, CAddrDB *pAddrDB=NULL);
void AddressCurrentlyConnected(const CAddress& addr);
CNode* FindNode(unsigned int ip);
bool RecvLine(SOCKET hSocket, std::string& strLine);
bool GetMyExternalIP(CNetAddr& ipRet);
void AddressCurrentlyConnected(const CService& addr);
CNode* FindNode(const CNetAddr& ip);
CNode* FindNode(const CService& ip);
CNode* ConnectNode(CAddress addrConnect, int64 nTimeout=0);
void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1);
bool AnySubscribed(unsigned int nChannel);
void MapPort(bool fMapPort);
bool BindListenPort(std::string& strError=REF(std::string()));
void StartNode(void* parg);
@@ -69,34 +66,43 @@ public:
};
/** Thread types */
enum threadId
{
THREAD_SOCKETHANDLER,
THREAD_OPENCONNECTIONS,
THREAD_MESSAGEHANDLER,
THREAD_MINER,
THREAD_RPCSERVER,
THREAD_UPNP,
THREAD_DNSSEED,
THREAD_ADDEDCONNECTIONS,
THREAD_DUMPADDRESS,
THREAD_MAX
};
extern bool fClient;
extern bool fAllowDNS;
extern uint64 nLocalServices;
extern CAddress addrLocalHost;
extern uint64 nLocalHostNonce;
extern boost::array<int, 10> vnThreadsRunning;
extern boost::array<int, THREAD_MAX> vnThreadsRunning;
extern CAddrMan addrman;
extern std::vector<CNode*> vNodes;
extern CCriticalSection cs_vNodes;
extern std::map<std::vector<unsigned char>, CAddress> mapAddresses;
extern CCriticalSection cs_mapAddresses;
extern std::map<CInv, CDataStream> mapRelay;
extern std::deque<std::pair<int64, CInv> > vRelayExpiration;
extern CCriticalSection cs_mapRelay;
extern std::map<CInv, int64> mapAlreadyAskedFor;
// Settings
extern int fUseProxy;
extern CAddress addrProxy;
/** Information about a peer */
class CNode
{
public:
@@ -111,7 +117,7 @@ public:
int64 nLastRecv;
int64 nLastSendEmpty;
int64 nTimeConnected;
unsigned int nHeaderStart;
int nHeaderStart;
unsigned int nMessageStart;
CAddress addr;
int nVersion;
@@ -126,7 +132,7 @@ protected:
// Denial-of-service detection/prevention
// Key is ip address, value is banned-until-time
static std::map<unsigned int, int64> setBanned;
static std::map<CNetAddr, int64> setBanned;
static CCriticalSection cs_setBanned;
int nMisbehavior;
@@ -146,28 +152,15 @@ public:
std::set<uint256> setKnown;
// inventory based relay
std::set<CInv> setInventoryKnown;
mruset<CInv> setInventoryKnown;
std::vector<CInv> vInventoryToSend;
CCriticalSection cs_inventory;
std::multimap<int64, CInv> mapAskFor;
// publish and subscription
std::vector<char> vfSubscribe;
CNode(SOCKET hSocketIn, CAddress addrIn, bool fInboundIn=false)
CNode(SOCKET hSocketIn, CAddress addrIn, bool fInboundIn=false) : vSend(SER_NETWORK, MIN_PROTO_VERSION), vRecv(SER_NETWORK, MIN_PROTO_VERSION)
{
nServices = 0;
hSocket = hSocketIn;
vSend.SetType(SER_NETWORK);
vSend.SetVersion(0);
vRecv.SetType(SER_NETWORK);
vRecv.SetVersion(0);
// Version 0.2 obsoletes 20 Feb 2012
if (GetTime() > 1329696000)
{
vSend.SetVersion(209);
vRecv.SetVersion(209);
}
nLastSend = 0;
nLastRecv = 0;
nLastSendEmpty = GetTime();
@@ -189,8 +182,8 @@ public:
hashLastGetBlocksEnd = 0;
nStartingHeight = -1;
fGetAddr = false;
vfSubscribe.assign(256, false);
nMisbehavior = 0;
setInventoryKnown.max_size(SendBufferSize() / 1000);
// Be shy and don't send version until we hear
if (!fInbound)
@@ -250,15 +243,19 @@ public:
void AddInventoryKnown(const CInv& inv)
{
CRITICAL_BLOCK(cs_inventory)
{
LOCK(cs_inventory);
setInventoryKnown.insert(inv);
}
}
void PushInventory(const CInv& inv)
{
CRITICAL_BLOCK(cs_inventory)
{
LOCK(cs_inventory);
if (!setInventoryKnown.count(inv))
vInventoryToSend.push_back(inv);
}
}
void AskFor(const CInv& inv)
@@ -271,7 +268,9 @@ public:
// Make sure not to reuse time indexes to keep things in the same order
int64 nNow = (GetTime() - 1) * 1000000;
static int64 nLastTime;
nLastTime = nNow = std::max(nNow, ++nLastTime);
++nLastTime;
nNow = std::max(nNow, nLastTime);
nLastTime = nNow;
// Each retry is 2 minutes after the last
nRequestTime = std::max(nRequestTime + 2 * 60 * 1000000, nNow);
@@ -282,7 +281,7 @@ public:
void BeginMessage(const char* pszCommand)
{
cs_vSend.Enter("cs_vSend", __FILE__, __LINE__);
ENTER_CRITICAL_SECTION(cs_vSend);
if (nHeaderStart != -1)
AbortMessage();
nHeaderStart = vSend.size();
@@ -296,12 +295,12 @@ public:
void AbortMessage()
{
if (nHeaderStart == -1)
if (nHeaderStart < 0)
return;
vSend.resize(nHeaderStart);
nHeaderStart = -1;
nMessageStart = -1;
cs_vSend.Leave();
LEAVE_CRITICAL_SECTION(cs_vSend);
if (fDebug)
printf("(aborted)\n");
@@ -316,7 +315,7 @@ public:
return;
}
if (nHeaderStart == -1)
if (nHeaderStart < 0)
return;
// Set the size
@@ -324,14 +323,11 @@ public:
memcpy((char*)&vSend[nHeaderStart] + offsetof(CMessageHeader, nMessageSize), &nSize, sizeof(nSize));
// Set the checksum
if (vSend.GetVersion() >= 209)
{
uint256 hash = Hash(vSend.begin() + nMessageStart, vSend.end());
unsigned int nChecksum = 0;
memcpy(&nChecksum, &hash, sizeof(nChecksum));
assert(nMessageStart - nHeaderStart >= offsetof(CMessageHeader, nChecksum) + sizeof(nChecksum));
memcpy((char*)&vSend[nHeaderStart] + offsetof(CMessageHeader, nChecksum), &nChecksum, sizeof(nChecksum));
}
uint256 hash = Hash(vSend.begin() + nMessageStart, vSend.end());
unsigned int nChecksum = 0;
memcpy(&nChecksum, &hash, sizeof(nChecksum));
assert(nMessageStart - nHeaderStart >= offsetof(CMessageHeader, nChecksum) + sizeof(nChecksum));
memcpy((char*)&vSend[nHeaderStart] + offsetof(CMessageHeader, nChecksum), &nChecksum, sizeof(nChecksum));
if (fDebug) {
printf("(%d bytes)\n", nSize);
@@ -339,12 +335,12 @@ public:
nHeaderStart = -1;
nMessageStart = -1;
cs_vSend.Leave();
LEAVE_CRITICAL_SECTION(cs_vSend);
}
void EndMessageAbortIfEmpty()
{
if (nHeaderStart == -1)
if (nHeaderStart < 0)
return;
int nSize = vSend.size() - nMessageStart;
if (nSize > 0)
@@ -355,18 +351,7 @@ public:
void PushVersion()
{
/// when NTP implemented, change to just nTime = GetAdjustedTime()
int64 nTime = (fInbound ? GetAdjustedTime() : GetTime());
CAddress addrYou = (fUseProxy ? CAddress("0.0.0.0") : addr);
CAddress addrMe = (fUseProxy ? CAddress("0.0.0.0") : addrLocalHost);
RAND_bytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce));
PushMessage("version", VERSION, nLocalServices, nTime, addrYou, addrMe,
nLocalHostNonce, std::string(pszSubVer), nBestHeight);
}
void PushVersion();
void PushMessage(const char* pszCommand)
@@ -534,8 +519,10 @@ public:
uint256 hashReply;
RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply));
CRITICAL_BLOCK(cs_mapRequests)
{
LOCK(cs_mapRequests);
mapRequests[hashReply] = CRequestTracker(fn, param1);
}
PushMessage(pszCommand, hashReply);
}
@@ -547,8 +534,10 @@ public:
uint256 hashReply;
RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply));
CRITICAL_BLOCK(cs_mapRequests)
{
LOCK(cs_mapRequests);
mapRequests[hashReply] = CRequestTracker(fn, param1);
}
PushMessage(pszCommand, hashReply, a1);
}
@@ -560,8 +549,10 @@ public:
uint256 hashReply;
RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply));
CRITICAL_BLOCK(cs_mapRequests)
{
LOCK(cs_mapRequests);
mapRequests[hashReply] = CRequestTracker(fn, param1);
}
PushMessage(pszCommand, hashReply, a1, a2);
}
@@ -591,7 +582,7 @@ public:
// between nodes running old code and nodes running
// new code.
static void ClearBanned(); // needed for unit testing
static bool IsBanned(unsigned int ip);
static bool IsBanned(CNetAddr ip);
bool Misbehaving(int howmuch); // 1 == a little, 100 == a lot
};
@@ -607,15 +598,17 @@ public:
inline void RelayInventory(const CInv& inv)
{
// Put on lists to offer to the other nodes
CRITICAL_BLOCK(cs_vNodes)
{
LOCK(cs_vNodes);
BOOST_FOREACH(CNode* pnode, vNodes)
pnode->PushInventory(inv);
}
}
template<typename T>
void RelayMessage(const CInv& inv, const T& a)
{
CDataStream ss(SER_NETWORK);
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
ss.reserve(10000);
ss << a;
RelayMessage(inv, ss);
@@ -624,8 +617,8 @@ void RelayMessage(const CInv& inv, const T& a)
template<>
inline void RelayMessage<>(const CInv& inv, const CDataStream& ss)
{
CRITICAL_BLOCK(cs_mapRelay)
{
LOCK(cs_mapRelay);
// Expire old relay messages
while (!vRelayExpiration.empty() && vRelayExpiration.front().first < GetTime())
{
@@ -634,7 +627,7 @@ inline void RelayMessage<>(const CInv& inv, const CDataStream& ss)
}
// Save original serialized message so newer versions are preserved
mapRelay[inv] = ss;
mapRelay.insert(std::make_pair(inv, ss));
vRelayExpiration.push_back(std::make_pair(GetTime() + 15 * 60, inv));
}
@@ -642,58 +635,4 @@ inline void RelayMessage<>(const CInv& inv, const CDataStream& ss)
}
//
// Templates for the publish and subscription system.
// The object being published as T& obj needs to have:
// a set<unsigned int> setSources member
// specializations of AdvertInsert and AdvertErase
// Currently implemented for CTable and CProduct.
//
template<typename T>
void AdvertStartPublish(CNode* pfrom, unsigned int nChannel, unsigned int nHops, T& obj)
{
// Add to sources
obj.setSources.insert(pfrom->addr.ip);
if (!AdvertInsert(obj))
return;
// Relay
CRITICAL_BLOCK(cs_vNodes)
BOOST_FOREACH(CNode* pnode, vNodes)
if (pnode != pfrom && (nHops < PUBLISH_HOPS || pnode->IsSubscribed(nChannel)))
pnode->PushMessage("publish", nChannel, nHops, obj);
}
template<typename T>
void AdvertStopPublish(CNode* pfrom, unsigned int nChannel, unsigned int nHops, T& obj)
{
uint256 hash = obj.GetHash();
CRITICAL_BLOCK(cs_vNodes)
BOOST_FOREACH(CNode* pnode, vNodes)
if (pnode != pfrom && (nHops < PUBLISH_HOPS || pnode->IsSubscribed(nChannel)))
pnode->PushMessage("pub-cancel", nChannel, nHops, hash);
AdvertErase(obj);
}
template<typename T>
void AdvertRemoveSource(CNode* pfrom, unsigned int nChannel, unsigned int nHops, T& obj)
{
// Remove a source
obj.setSources.erase(pfrom->addr.ip);
// If no longer supported by any sources, cancel it
if (obj.setSources.empty())
AdvertStopPublish(pfrom, nChannel, nHops, obj);
}
#endif

738
src/netbase.cpp Normal file
View File

@@ -0,0 +1,738 @@
// 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.
#include "netbase.h"
#include "util.h"
#ifndef WIN32
#include <sys/fcntl.h>
#endif
#include "strlcpy.h"
using namespace std;
// Settings
int fUseProxy = false;
CService addrProxy("127.0.0.1",9050);
int nConnectTimeout = 5000;
static const unsigned char pchIPv4[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff };
bool static LookupIntern(const char *pszName, std::vector<CNetAddr>& vIP, unsigned int nMaxSolutions, bool fAllowLookup)
{
vIP.clear();
struct addrinfo aiHint;
memset(&aiHint, 0, sizeof(struct addrinfo));
aiHint.ai_socktype = SOCK_STREAM;
aiHint.ai_protocol = IPPROTO_TCP;
#ifdef WIN32
# ifdef USE_IPV6
aiHint.ai_family = AF_UNSPEC;
aiHint.ai_flags = fAllowLookup ? 0 : AI_NUMERICHOST;
# else
aiHint.ai_family = AF_INET;
aiHint.ai_flags = fAllowLookup ? 0 : AI_NUMERICHOST;
# endif
#else
# ifdef USE_IPV6
aiHint.ai_family = AF_UNSPEC;
aiHint.ai_flags = AI_ADDRCONFIG | (fAllowLookup ? 0 : AI_NUMERICHOST);
# else
aiHint.ai_family = AF_INET;
aiHint.ai_flags = AI_ADDRCONFIG | (fAllowLookup ? 0 : AI_NUMERICHOST);
# endif
#endif
struct addrinfo *aiRes = NULL;
int nErr = getaddrinfo(pszName, NULL, &aiHint, &aiRes);
if (nErr)
return false;
struct addrinfo *aiTrav = aiRes;
while (aiTrav != NULL && (nMaxSolutions == 0 || vIP.size() < nMaxSolutions))
{
if (aiTrav->ai_family == AF_INET)
{
assert(aiTrav->ai_addrlen >= sizeof(sockaddr_in));
vIP.push_back(CNetAddr(((struct sockaddr_in*)(aiTrav->ai_addr))->sin_addr));
}
#ifdef USE_IPV6
if (aiTrav->ai_family == AF_INET6)
{
assert(aiTrav->ai_addrlen >= sizeof(sockaddr_in6));
vIP.push_back(CNetAddr(((struct sockaddr_in6*)(aiTrav->ai_addr))->sin6_addr));
}
#endif
aiTrav = aiTrav->ai_next;
}
freeaddrinfo(aiRes);
return (vIP.size() > 0);
}
bool LookupHost(const char *pszName, std::vector<CNetAddr>& vIP, unsigned int nMaxSolutions, bool fAllowLookup)
{
if (pszName[0] == 0)
return false;
char psz[256];
char *pszHost = psz;
strlcpy(psz, pszName, sizeof(psz));
if (psz[0] == '[' && psz[strlen(psz)-1] == ']')
{
pszHost = psz+1;
psz[strlen(psz)-1] = 0;
}
return LookupIntern(pszHost, vIP, nMaxSolutions, fAllowLookup);
}
bool LookupHostNumeric(const char *pszName, std::vector<CNetAddr>& vIP, unsigned int nMaxSolutions)
{
return LookupHost(pszName, vIP, nMaxSolutions, false);
}
bool Lookup(const char *pszName, std::vector<CService>& vAddr, int portDefault, bool fAllowLookup, unsigned int nMaxSolutions)
{
if (pszName[0] == 0)
return false;
int port = portDefault;
char psz[256];
char *pszHost = psz;
strlcpy(psz, pszName, sizeof(psz));
char* pszColon = strrchr(psz+1,':');
char *pszPortEnd = NULL;
int portParsed = pszColon ? strtoul(pszColon+1, &pszPortEnd, 10) : 0;
if (pszColon && pszPortEnd && pszPortEnd[0] == 0)
{
if (psz[0] == '[' && pszColon[-1] == ']')
{
pszHost = psz+1;
pszColon[-1] = 0;
}
else
pszColon[0] = 0;
if (port >= 0 && port <= USHRT_MAX)
port = portParsed;
}
else
{
if (psz[0] == '[' && psz[strlen(psz)-1] == ']')
{
pszHost = psz+1;
psz[strlen(psz)-1] = 0;
}
}
std::vector<CNetAddr> vIP;
bool fRet = LookupIntern(pszHost, vIP, nMaxSolutions, fAllowLookup);
if (!fRet)
return false;
vAddr.resize(vIP.size());
for (unsigned int i = 0; i < vIP.size(); i++)
vAddr[i] = CService(vIP[i], port);
return true;
}
bool Lookup(const char *pszName, CService& addr, int portDefault, bool fAllowLookup)
{
std::vector<CService> vService;
bool fRet = Lookup(pszName, vService, portDefault, fAllowLookup, 1);
if (!fRet)
return false;
addr = vService[0];
return true;
}
bool LookupNumeric(const char *pszName, CService& addr, int portDefault)
{
return Lookup(pszName, addr, portDefault, false);
}
bool ConnectSocket(const CService &addrDest, SOCKET& hSocketRet, int nTimeout)
{
hSocketRet = INVALID_SOCKET;
SOCKET hSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (hSocket == INVALID_SOCKET)
return false;
#ifdef SO_NOSIGPIPE
int set = 1;
setsockopt(hSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&set, sizeof(int));
#endif
bool fProxy = (fUseProxy && addrDest.IsRoutable());
struct sockaddr_in sockaddr;
if (fProxy)
addrProxy.GetSockAddr(&sockaddr);
else
addrDest.GetSockAddr(&sockaddr);
#ifdef WIN32
u_long fNonblock = 1;
if (ioctlsocket(hSocket, FIONBIO, &fNonblock) == SOCKET_ERROR)
#else
int fFlags = fcntl(hSocket, F_GETFL, 0);
if (fcntl(hSocket, F_SETFL, fFlags | O_NONBLOCK) == -1)
#endif
{
closesocket(hSocket);
return false;
}
if (connect(hSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
{
// WSAEINVAL is here because some legacy version of winsock uses it
if (WSAGetLastError() == WSAEINPROGRESS || WSAGetLastError() == WSAEWOULDBLOCK || WSAGetLastError() == WSAEINVAL)
{
struct timeval timeout;
timeout.tv_sec = nTimeout / 1000;
timeout.tv_usec = (nTimeout % 1000) * 1000;
fd_set fdset;
FD_ZERO(&fdset);
FD_SET(hSocket, &fdset);
int nRet = select(hSocket + 1, NULL, &fdset, NULL, &timeout);
if (nRet == 0)
{
printf("connection timeout\n");
closesocket(hSocket);
return false;
}
if (nRet == SOCKET_ERROR)
{
printf("select() for connection failed: %i\n",WSAGetLastError());
closesocket(hSocket);
return false;
}
socklen_t nRetSize = sizeof(nRet);
#ifdef WIN32
if (getsockopt(hSocket, SOL_SOCKET, SO_ERROR, (char*)(&nRet), &nRetSize) == SOCKET_ERROR)
#else
if (getsockopt(hSocket, SOL_SOCKET, SO_ERROR, &nRet, &nRetSize) == SOCKET_ERROR)
#endif
{
printf("getsockopt() for connection failed: %i\n",WSAGetLastError());
closesocket(hSocket);
return false;
}
if (nRet != 0)
{
printf("connect() failed after select(): %s\n",strerror(nRet));
closesocket(hSocket);
return false;
}
}
#ifdef WIN32
else if (WSAGetLastError() != WSAEISCONN)
#else
else
#endif
{
printf("connect() failed: %i\n",WSAGetLastError());
closesocket(hSocket);
return false;
}
}
// this isn't even strictly necessary
// CNode::ConnectNode immediately turns the socket back to non-blocking
// but we'll turn it back to blocking just in case
#ifdef WIN32
fNonblock = 0;
if (ioctlsocket(hSocket, FIONBIO, &fNonblock) == SOCKET_ERROR)
#else
fFlags = fcntl(hSocket, F_GETFL, 0);
if (fcntl(hSocket, F_SETFL, fFlags & !O_NONBLOCK) == SOCKET_ERROR)
#endif
{
closesocket(hSocket);
return false;
}
if (fProxy)
{
printf("proxy connecting %s\n", addrDest.ToString().c_str());
char pszSocks4IP[] = "\4\1\0\0\0\0\0\0user";
struct sockaddr_in addr;
addrDest.GetSockAddr(&addr);
memcpy(pszSocks4IP + 2, &addr.sin_port, 2);
memcpy(pszSocks4IP + 4, &addr.sin_addr, 4);
char* pszSocks4 = pszSocks4IP;
int nSize = sizeof(pszSocks4IP);
int ret = send(hSocket, pszSocks4, nSize, MSG_NOSIGNAL);
if (ret != nSize)
{
closesocket(hSocket);
return error("Error sending to proxy");
}
char pchRet[8];
if (recv(hSocket, pchRet, 8, 0) != 8)
{
closesocket(hSocket);
return error("Error reading proxy response");
}
if (pchRet[1] != 0x5a)
{
closesocket(hSocket);
if (pchRet[1] != 0x5b)
printf("ERROR: Proxy returned error %d\n", pchRet[1]);
return false;
}
printf("proxy connected %s\n", addrDest.ToString().c_str());
}
hSocketRet = hSocket;
return true;
}
void CNetAddr::Init()
{
memset(ip, 0, 16);
}
void CNetAddr::SetIP(const CNetAddr& ipIn)
{
memcpy(ip, ipIn.ip, sizeof(ip));
}
CNetAddr::CNetAddr()
{
Init();
}
CNetAddr::CNetAddr(const struct in_addr& ipv4Addr)
{
memcpy(ip, pchIPv4, 12);
memcpy(ip+12, &ipv4Addr, 4);
}
#ifdef USE_IPV6
CNetAddr::CNetAddr(const struct in6_addr& ipv6Addr)
{
memcpy(ip, &ipv6Addr, 16);
}
#endif
CNetAddr::CNetAddr(const char *pszIp, bool fAllowLookup)
{
Init();
std::vector<CNetAddr> vIP;
if (LookupHost(pszIp, vIP, 1, fAllowLookup))
*this = vIP[0];
}
CNetAddr::CNetAddr(const std::string &strIp, bool fAllowLookup)
{
Init();
std::vector<CNetAddr> vIP;
if (LookupHost(strIp.c_str(), vIP, 1, fAllowLookup))
*this = vIP[0];
}
int CNetAddr::GetByte(int n) const
{
return ip[15-n];
}
bool CNetAddr::IsIPv4() const
{
return (memcmp(ip, pchIPv4, sizeof(pchIPv4)) == 0);
}
bool CNetAddr::IsRFC1918() const
{
return IsIPv4() && (
GetByte(3) == 10 ||
(GetByte(3) == 192 && GetByte(2) == 168) ||
(GetByte(3) == 172 && (GetByte(2) >= 16 && GetByte(2) <= 31)));
}
bool CNetAddr::IsRFC3927() const
{
return IsIPv4() && (GetByte(3) == 169 && GetByte(2) == 254);
}
bool CNetAddr::IsRFC3849() const
{
return GetByte(15) == 0x20 && GetByte(14) == 0x01 && GetByte(13) == 0x0D && GetByte(12) == 0xB8;
}
bool CNetAddr::IsRFC3964() const
{
return (GetByte(15) == 0x20 && GetByte(14) == 0x02);
}
bool CNetAddr::IsRFC6052() const
{
static const unsigned char pchRFC6052[] = {0,0x64,0xFF,0x9B,0,0,0,0,0,0,0,0};
return (memcmp(ip, pchRFC6052, sizeof(pchRFC6052)) == 0);
}
bool CNetAddr::IsRFC4380() const
{
return (GetByte(15) == 0x20 && GetByte(14) == 0x01 && GetByte(13) == 0 && GetByte(12) == 0);
}
bool CNetAddr::IsRFC4862() const
{
static const unsigned char pchRFC4862[] = {0xFE,0x80,0,0,0,0,0,0};
return (memcmp(ip, pchRFC4862, sizeof(pchRFC4862)) == 0);
}
bool CNetAddr::IsRFC4193() const
{
return ((GetByte(15) & 0xFE) == 0xFC);
}
bool CNetAddr::IsRFC6145() const
{
static const unsigned char pchRFC6145[] = {0,0,0,0,0,0,0,0,0xFF,0xFF,0,0};
return (memcmp(ip, pchRFC6145, sizeof(pchRFC6145)) == 0);
}
bool CNetAddr::IsRFC4843() const
{
return (GetByte(15) == 0x20 && GetByte(14) == 0x01 && GetByte(13) == 0x00 && (GetByte(12) & 0xF0) == 0x10);
}
bool CNetAddr::IsLocal() const
{
// IPv4 loopback
if (IsIPv4() && (GetByte(3) == 127 || GetByte(3) == 0))
return true;
// IPv6 loopback (::1/128)
static const unsigned char pchLocal[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1};
if (memcmp(ip, pchLocal, 16) == 0)
return true;
return false;
}
bool CNetAddr::IsMulticast() const
{
return (IsIPv4() && (GetByte(3) & 0xF0) == 0xE0)
|| (GetByte(15) == 0xFF);
}
bool CNetAddr::IsValid() const
{
// Clean up 3-byte shifted addresses caused by garbage in size field
// of addr messages from versions before 0.2.9 checksum.
// Two consecutive addr messages look like this:
// header20 vectorlen3 addr26 addr26 addr26 header20 vectorlen3 addr26 addr26 addr26...
// so if the first length field is garbled, it reads the second batch
// of addr misaligned by 3 bytes.
if (memcmp(ip, pchIPv4+3, sizeof(pchIPv4)-3) == 0)
return false;
// unspecified IPv6 address (::/128)
unsigned char ipNone[16] = {};
if (memcmp(ip, ipNone, 16) == 0)
return false;
// documentation IPv6 address
if (IsRFC3849())
return false;
if (IsIPv4())
{
// INADDR_NONE
uint32_t ipNone = INADDR_NONE;
if (memcmp(ip+12, &ipNone, 4) == 0)
return false;
// 0
ipNone = 0;
if (memcmp(ip+12, &ipNone, 4) == 0)
return false;
}
return true;
}
bool CNetAddr::IsRoutable() const
{
return IsValid() && !(IsRFC1918() || IsRFC3927() || IsRFC4862() || IsRFC4193() || IsRFC4843() || IsLocal());
}
std::string CNetAddr::ToStringIP() const
{
if (IsIPv4())
return strprintf("%u.%u.%u.%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0));
else
return strprintf("%x:%x:%x:%x:%x:%x:%x:%x",
GetByte(15) << 8 | GetByte(14), GetByte(13) << 8 | GetByte(12),
GetByte(11) << 8 | GetByte(10), GetByte(9) << 8 | GetByte(8),
GetByte(7) << 8 | GetByte(6), GetByte(5) << 8 | GetByte(4),
GetByte(3) << 8 | GetByte(2), GetByte(1) << 8 | GetByte(0));
}
std::string CNetAddr::ToString() const
{
return ToStringIP();
}
bool operator==(const CNetAddr& a, const CNetAddr& b)
{
return (memcmp(a.ip, b.ip, 16) == 0);
}
bool operator!=(const CNetAddr& a, const CNetAddr& b)
{
return (memcmp(a.ip, b.ip, 16) != 0);
}
bool operator<(const CNetAddr& a, const CNetAddr& b)
{
return (memcmp(a.ip, b.ip, 16) < 0);
}
bool CNetAddr::GetInAddr(struct in_addr* pipv4Addr) const
{
if (!IsIPv4())
return false;
memcpy(pipv4Addr, ip+12, 4);
return true;
}
#ifdef USE_IPV6
bool CNetAddr::GetIn6Addr(struct in6_addr* pipv6Addr) const
{
memcpy(pipv6Addr, ip, 16);
return true;
}
#endif
// get canonical identifier of an address' group
// no two connections will be attempted to addresses with the same group
std::vector<unsigned char> CNetAddr::GetGroup() const
{
std::vector<unsigned char> vchRet;
int nClass = 0; // 0=IPv6, 1=IPv4, 254=local, 255=unroutable
int nStartByte = 0;
int nBits = 16;
// all local addresses belong to the same group
if (IsLocal())
{
nClass = 254;
nBits = 0;
}
// all unroutable addresses belong to the same group
if (!IsRoutable())
{
nClass = 255;
nBits = 0;
}
// for IPv4 addresses, '1' + the 16 higher-order bits of the IP
// includes mapped IPv4, SIIT translated IPv4, and the well-known prefix
else if (IsIPv4() || IsRFC6145() || IsRFC6052())
{
nClass = 1;
nStartByte = 12;
}
// for 6to4 tunneled addresses, use the encapsulated IPv4 address
else if (IsRFC3964())
{
nClass = 1;
nStartByte = 2;
}
// for Teredo-tunneled IPv6 addresses, use the encapsulated IPv4 address
else if (IsRFC4380())
{
vchRet.push_back(1);
vchRet.push_back(GetByte(3) ^ 0xFF);
vchRet.push_back(GetByte(2) ^ 0xFF);
return vchRet;
}
// for he.net, use /36 groups
else if (GetByte(15) == 0x20 && GetByte(14) == 0x11 && GetByte(13) == 0x04 && GetByte(12) == 0x70)
nBits = 36;
// for the rest of the IPv6 network, use /32 groups
else
nBits = 32;
vchRet.push_back(nClass);
while (nBits >= 8)
{
vchRet.push_back(GetByte(15 - nStartByte));
nStartByte++;
nBits -= 8;
}
if (nBits > 0)
vchRet.push_back(GetByte(15 - nStartByte) | ((1 << nBits) - 1));
return vchRet;
}
int64 CNetAddr::GetHash() const
{
uint256 hash = Hash(&ip[0], &ip[16]);
int64 nRet;
memcpy(&nRet, &hash, sizeof(nRet));
return nRet;
}
void CNetAddr::print() const
{
printf("CNetAddr(%s)\n", ToString().c_str());
}
void CService::Init()
{
port = 0;
}
CService::CService()
{
Init();
}
CService::CService(const CNetAddr& cip, unsigned short portIn) : CNetAddr(cip), port(portIn)
{
}
CService::CService(const struct in_addr& ipv4Addr, unsigned short portIn) : CNetAddr(ipv4Addr), port(portIn)
{
}
#ifdef USE_IPV6
CService::CService(const struct in6_addr& ipv6Addr, unsigned short portIn) : CNetAddr(ipv6Addr), port(portIn)
{
}
#endif
CService::CService(const struct sockaddr_in& addr) : CNetAddr(addr.sin_addr), port(ntohs(addr.sin_port))
{
assert(addr.sin_family == AF_INET);
}
#ifdef USE_IPV6
CService::CService(const struct sockaddr_in6 &addr) : CNetAddr(addr.sin6_addr), port(ntohs(addr.sin6_port))
{
assert(addr.sin6_family == AF_INET6);
}
#endif
CService::CService(const char *pszIpPort, bool fAllowLookup)
{
Init();
CService ip;
if (Lookup(pszIpPort, ip, 0, fAllowLookup))
*this = ip;
}
CService::CService(const char *pszIpPort, int portDefault, bool fAllowLookup)
{
Init();
CService ip;
if (Lookup(pszIpPort, ip, portDefault, fAllowLookup))
*this = ip;
}
CService::CService(const std::string &strIpPort, bool fAllowLookup)
{
Init();
CService ip;
if (Lookup(strIpPort.c_str(), ip, 0, fAllowLookup))
*this = ip;
}
CService::CService(const std::string &strIpPort, int portDefault, bool fAllowLookup)
{
Init();
CService ip;
if (Lookup(strIpPort.c_str(), ip, portDefault, fAllowLookup))
*this = ip;
}
unsigned short CService::GetPort() const
{
return port;
}
bool operator==(const CService& a, const CService& b)
{
return (CNetAddr)a == (CNetAddr)b && a.port == b.port;
}
bool operator!=(const CService& a, const CService& b)
{
return (CNetAddr)a != (CNetAddr)b || a.port != b.port;
}
bool operator<(const CService& a, const CService& b)
{
return (CNetAddr)a < (CNetAddr)b || ((CNetAddr)a == (CNetAddr)b && a.port < b.port);
}
bool CService::GetSockAddr(struct sockaddr_in* paddr) const
{
if (!IsIPv4())
return false;
memset(paddr, 0, sizeof(struct sockaddr_in));
if (!GetInAddr(&paddr->sin_addr))
return false;
paddr->sin_family = AF_INET;
paddr->sin_port = htons(port);
return true;
}
#ifdef USE_IPV6
bool CService::GetSockAddr6(struct sockaddr_in6* paddr) const
{
memset(paddr, 0, sizeof(struct sockaddr_in6));
if (!GetIn6Addr(&paddr->sin6_addr))
return false;
paddr->sin6_family = AF_INET6;
paddr->sin6_port = htons(port);
return true;
}
#endif
std::vector<unsigned char> CService::GetKey() const
{
std::vector<unsigned char> vKey;
vKey.resize(18);
memcpy(&vKey[0], ip, 16);
vKey[16] = port / 0x100;
vKey[17] = port & 0x0FF;
return vKey;
}
std::string CService::ToStringPort() const
{
return strprintf(":%i", port);
}
std::string CService::ToStringIPPort() const
{
return ToStringIP() + ToStringPort();
}
std::string CService::ToString() const
{
return ToStringIPPort();
}
void CService::print() const
{
printf("CService(%s)\n", ToString().c_str());
}
void CService::SetPort(unsigned short portIn)
{
port = portIn;
}

127
src/netbase.h Normal file
View File

@@ -0,0 +1,127 @@
// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_NETBASE_H
#define BITCOIN_NETBASE_H
#include <string>
#include <vector>
#include "serialize.h"
#include "compat.h"
extern int nConnectTimeout;
#ifdef WIN32
// In MSVC, this is defined as a macro, undefine it to prevent a compile and link error
#undef SetPort
#endif
/** IP address (IPv6, or IPv4 using mapped IPv6 range (::FFFF:0:0/96)) */
class CNetAddr
{
protected:
unsigned char ip[16]; // in network byte order
public:
CNetAddr();
CNetAddr(const struct in_addr& ipv4Addr);
explicit CNetAddr(const char *pszIp, bool fAllowLookup = false);
explicit CNetAddr(const std::string &strIp, bool fAllowLookup = false);
void Init();
void SetIP(const CNetAddr& ip);
bool IsIPv4() const; // IPv4 mapped address (::FFFF:0:0/96, 0.0.0.0/0)
bool IsRFC1918() const; // IPv4 private networks (10.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12)
bool IsRFC3849() const; // IPv6 documentation address (2001:0DB8::/32)
bool IsRFC3927() const; // IPv4 autoconfig (169.254.0.0/16)
bool IsRFC3964() const; // IPv6 6to4 tunneling (2002::/16)
bool IsRFC4193() const; // IPv6 unique local (FC00::/15)
bool IsRFC4380() const; // IPv6 Teredo tunneling (2001::/32)
bool IsRFC4843() const; // IPv6 ORCHID (2001:10::/28)
bool IsRFC4862() const; // IPv6 autoconfig (FE80::/64)
bool IsRFC6052() const; // IPv6 well-known prefix (64:FF9B::/96)
bool IsRFC6145() const; // IPv6 IPv4-translated address (::FFFF:0:0:0/96)
bool IsLocal() const;
bool IsRoutable() const;
bool IsValid() const;
bool IsMulticast() const;
std::string ToString() const;
std::string ToStringIP() const;
int GetByte(int n) const;
int64 GetHash() const;
bool GetInAddr(struct in_addr* pipv4Addr) const;
std::vector<unsigned char> GetGroup() const;
void print() const;
#ifdef USE_IPV6
CNetAddr(const struct in6_addr& pipv6Addr);
bool GetIn6Addr(struct in6_addr* pipv6Addr) const;
#endif
friend bool operator==(const CNetAddr& a, const CNetAddr& b);
friend bool operator!=(const CNetAddr& a, const CNetAddr& b);
friend bool operator<(const CNetAddr& a, const CNetAddr& b);
IMPLEMENT_SERIALIZE
(
READWRITE(FLATDATA(ip));
)
};
/** A combination of a network address (CNetAddr) and a (TCP) port */
class CService : public CNetAddr
{
protected:
unsigned short port; // host order
public:
CService();
CService(const CNetAddr& ip, unsigned short port);
CService(const struct in_addr& ipv4Addr, unsigned short port);
CService(const struct sockaddr_in& addr);
explicit CService(const char *pszIpPort, int portDefault, bool fAllowLookup = false);
explicit CService(const char *pszIpPort, bool fAllowLookup = false);
explicit CService(const std::string& strIpPort, int portDefault, bool fAllowLookup = false);
explicit CService(const std::string& strIpPort, bool fAllowLookup = false);
void Init();
void SetPort(unsigned short portIn);
unsigned short GetPort() const;
bool GetSockAddr(struct sockaddr_in* paddr) const;
friend bool operator==(const CService& a, const CService& b);
friend bool operator!=(const CService& a, const CService& b);
friend bool operator<(const CService& a, const CService& b);
std::vector<unsigned char> GetKey() const;
std::string ToString() const;
std::string ToStringPort() const;
std::string ToStringIPPort() const;
void print() const;
#ifdef USE_IPV6
CService(const struct in6_addr& ipv6Addr, unsigned short port);
bool GetSockAddr6(struct sockaddr_in6* paddr) const;
CService(const struct sockaddr_in6& addr);
#endif
IMPLEMENT_SERIALIZE
(
CService* pthis = const_cast<CService*>(this);
READWRITE(FLATDATA(ip));
unsigned short portN = htons(port);
READWRITE(portN);
if (fRead)
pthis->port = ntohs(portN);
)
};
bool LookupHost(const char *pszName, std::vector<CNetAddr>& vIP, unsigned int nMaxSolutions = 0, bool fAllowLookup = true);
bool LookupHostNumeric(const char *pszName, std::vector<CNetAddr>& vIP, unsigned int nMaxSolutions = 0);
bool Lookup(const char *pszName, CService& addr, int portDefault = 0, bool fAllowLookup = true);
bool Lookup(const char *pszName, std::vector<CService>& vAddr, int portDefault = 0, bool fAllowLookup = true, unsigned int nMaxSolutions = 0);
bool LookupNumeric(const char *pszName, CService& addr, int portDefault = 0);
bool ConnectSocket(const CService &addr, SOCKET& hSocketRet, int nTimeout = nConnectTimeout);
// Settings
extern int fUseProxy;
extern CService addrProxy;
#endif

44
src/noui.cpp Normal file
View File

@@ -0,0 +1,44 @@
// 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.
#include "ui_interface.h"
#include <string>
#include "init.h"
int ThreadSafeMessageBox(const std::string& message, const std::string& caption, int style)
{
printf("%s: %s\n", caption.c_str(), message.c_str());
fprintf(stderr, "%s: %s\n", caption.c_str(), message.c_str());
return 4;
}
bool ThreadSafeAskFee(int64 nFeeRequired, const std::string& strCaption)
{
return true;
}
void MainFrameRepaint()
{
}
void AddressBookRepaint()
{
}
void InitMessage(const std::string &message)
{
}
std::string _(const char* psz)
{
return psz;
}
void QueueShutdown()
{
// Without UI, Shutdown can simply be started in a new thread
CreateThread(Shutdown, NULL);
}

View File

@@ -1,74 +0,0 @@
// Copyright (c) 2010 Satoshi Nakamoto
// Copyright (c) 2011 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_NOUI_H
#define BITCOIN_NOUI_H
#include <string>
#include <boost/function.hpp>
#include "wallet.h"
typedef void wxWindow;
#define wxYES 0x00000002
#define wxOK 0x00000004
#define wxNO 0x00000008
#define wxYES_NO (wxYES|wxNO)
#define wxCANCEL 0x00000010
#define wxAPPLY 0x00000020
#define wxCLOSE 0x00000040
#define wxOK_DEFAULT 0x00000000
#define wxYES_DEFAULT 0x00000000
#define wxNO_DEFAULT 0x00000080
#define wxCANCEL_DEFAULT 0x80000000
#define wxICON_EXCLAMATION 0x00000100
#define wxICON_HAND 0x00000200
#define wxICON_WARNING wxICON_EXCLAMATION
#define wxICON_ERROR wxICON_HAND
#define wxICON_QUESTION 0x00000400
#define wxICON_INFORMATION 0x00000800
#define wxICON_STOP wxICON_HAND
#define wxICON_ASTERISK wxICON_INFORMATION
#define wxICON_MASK (0x00000100|0x00000200|0x00000400|0x00000800)
#define wxFORWARD 0x00001000
#define wxBACKWARD 0x00002000
#define wxRESET 0x00004000
#define wxHELP 0x00008000
#define wxMORE 0x00010000
#define wxSETUP 0x00020000
inline int MyMessageBox(const std::string& message, const std::string& caption="Message", int style=wxOK, wxWindow* parent=NULL, int x=-1, int y=-1)
{
printf("%s: %s\n", caption.c_str(), message.c_str());
fprintf(stderr, "%s: %s\n", caption.c_str(), message.c_str());
return 4;
}
#define wxMessageBox MyMessageBox
inline int ThreadSafeMessageBox(const std::string& message, const std::string& caption, int style=wxOK, wxWindow* parent=NULL, int x=-1, int y=-1)
{
return MyMessageBox(message, caption, style, parent, x, y);
}
inline bool ThreadSafeAskFee(int64 nFeeRequired, const std::string& strCaption, wxWindow* parent)
{
return true;
}
inline void CalledSetStatusBar(const std::string& strText, int nField)
{
}
inline void UIThreadCall(boost::function0<void> fn)
{
}
inline void MainFrameRepaint()
{
}
inline void InitMessage(const std::string &message)
{
}
#endif

View File

@@ -1,2 +0,0 @@
*
!.gitignore

View File

@@ -1,20 +1,16 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2011 The Bitcoin developers
// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
#include "protocol.h"
#include "util.h"
#include "netbase.h"
#ifndef WIN32
# include <arpa/inet.h>
#endif
// Prototypes from net.h, but that header (currently) stinks, can't #include it without breaking things
bool Lookup(const char *pszName, std::vector<CAddress>& vaddr, int nServices, int nMaxSolutions, bool fAllowLookup = false, int portDefault = 0, bool fAllowPort = false);
bool Lookup(const char *pszName, CAddress& addr, int nServices, bool fAllowLookup = false, int portDefault = 0, bool fAllowPort = false);
static const unsigned char pchIPv4[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff };
static const char* ppszTypeName[] =
{
"ERROR",
@@ -77,185 +73,26 @@ bool CMessageHeader::IsValid() const
return true;
}
CAddress::CAddress()
CAddress::CAddress() : CService()
{
Init();
}
CAddress::CAddress(unsigned int ipIn, unsigned short portIn, uint64 nServicesIn)
CAddress::CAddress(CService ipIn, uint64 nServicesIn) : CService(ipIn)
{
Init();
ip = ipIn;
port = htons(portIn == 0 ? GetDefaultPort() : portIn);
nServices = nServicesIn;
}
CAddress::CAddress(const struct sockaddr_in& sockaddr, uint64 nServicesIn)
{
Init();
ip = sockaddr.sin_addr.s_addr;
port = sockaddr.sin_port;
nServices = nServicesIn;
}
CAddress::CAddress(const char* pszIn, int portIn, bool fNameLookup, uint64 nServicesIn)
{
Init();
Lookup(pszIn, *this, nServicesIn, fNameLookup, portIn);
}
CAddress::CAddress(const char* pszIn, bool fNameLookup, uint64 nServicesIn)
{
Init();
Lookup(pszIn, *this, nServicesIn, fNameLookup, 0, true);
}
CAddress::CAddress(std::string strIn, int portIn, bool fNameLookup, uint64 nServicesIn)
{
Init();
Lookup(strIn.c_str(), *this, nServicesIn, fNameLookup, portIn);
}
CAddress::CAddress(std::string strIn, bool fNameLookup, uint64 nServicesIn)
{
Init();
Lookup(strIn.c_str(), *this, nServicesIn, fNameLookup, 0, true);
}
void CAddress::Init()
{
nServices = NODE_NETWORK;
memcpy(pchReserved, pchIPv4, sizeof(pchReserved));
ip = INADDR_NONE;
port = htons(GetDefaultPort());
nTime = 100000000;
nLastTry = 0;
}
bool operator==(const CAddress& a, const CAddress& b)
{
return (memcmp(a.pchReserved, b.pchReserved, sizeof(a.pchReserved)) == 0 &&
a.ip == b.ip &&
a.port == b.port);
}
bool operator!=(const CAddress& a, const CAddress& b)
{
return (!(a == b));
}
bool operator<(const CAddress& a, const CAddress& b)
{
int ret = memcmp(a.pchReserved, b.pchReserved, sizeof(a.pchReserved));
if (ret < 0)
return true;
else if (ret == 0)
{
if (ntohl(a.ip) < ntohl(b.ip))
return true;
else if (a.ip == b.ip)
return ntohs(a.port) < ntohs(b.port);
}
return false;
}
std::vector<unsigned char> CAddress::GetKey() const
{
CDataStream ss;
ss.reserve(18);
ss << FLATDATA(pchReserved) << ip << port;
#if defined(_MSC_VER) && _MSC_VER < 1300
return std::vector<unsigned char>((unsigned char*)&ss.begin()[0], (unsigned char*)&ss.end()[0]);
#else
return std::vector<unsigned char>(ss.begin(), ss.end());
#endif
}
struct sockaddr_in CAddress::GetSockAddr() const
{
struct sockaddr_in sockaddr;
memset(&sockaddr, 0, sizeof(sockaddr));
sockaddr.sin_family = AF_INET;
sockaddr.sin_addr.s_addr = ip;
sockaddr.sin_port = port;
return sockaddr;
}
bool CAddress::IsIPv4() const
{
return (memcmp(pchReserved, pchIPv4, sizeof(pchIPv4)) == 0);
}
bool CAddress::IsRFC1918() const
{
return IsIPv4() && (GetByte(3) == 10 ||
(GetByte(3) == 192 && GetByte(2) == 168) ||
(GetByte(3) == 172 &&
(GetByte(2) >= 16 && GetByte(2) <= 31)));
}
bool CAddress::IsRFC3927() const
{
return IsIPv4() && (GetByte(3) == 169 && GetByte(2) == 254);
}
bool CAddress::IsLocal() const
{
return IsIPv4() && (GetByte(3) == 127 ||
GetByte(3) == 0);
}
bool CAddress::IsRoutable() const
{
return IsValid() &&
!(IsRFC1918() || IsRFC3927() || IsLocal());
}
bool CAddress::IsValid() const
{
// Clean up 3-byte shifted addresses caused by garbage in size field
// of addr messages from versions before 0.2.9 checksum.
// Two consecutive addr messages look like this:
// header20 vectorlen3 addr26 addr26 addr26 header20 vectorlen3 addr26 addr26 addr26...
// so if the first length field is garbled, it reads the second batch
// of addr misaligned by 3 bytes.
if (memcmp(pchReserved, pchIPv4+3, sizeof(pchIPv4)-3) == 0)
return false;
return (ip != 0 && ip != INADDR_NONE && port != htons(USHRT_MAX));
}
unsigned char CAddress::GetByte(int n) const
{
return ((unsigned char*)&ip)[3-n];
}
std::string CAddress::ToStringIPPort() const
{
return strprintf("%u.%u.%u.%u:%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0), ntohs(port));
}
std::string CAddress::ToStringIP() const
{
return strprintf("%u.%u.%u.%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0));
}
std::string CAddress::ToStringPort() const
{
return strprintf("%u", ntohs(port));
}
std::string CAddress::ToString() const
{
return strprintf("%u.%u.%u.%u:%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0), ntohs(port));
}
void CAddress::print() const
{
printf("CAddress(%s)\n", ToString().c_str());
}
CInv::CInv()
{
type = 0;
@@ -270,7 +107,7 @@ CInv::CInv(int typeIn, const uint256& hashIn)
CInv::CInv(const std::string& strType, const uint256& hashIn)
{
int i;
unsigned int i;
for (i = 1; i < ARRAYLEN(ppszTypeName); i++)
{
if (strType == ppszTypeName[i])
@@ -291,7 +128,7 @@ bool operator<(const CInv& a, const CInv& b)
bool CInv::IsKnownType() const
{
return (type >= 1 && type < ARRAYLEN(ppszTypeName));
return (type >= 1 && type < (int)ARRAYLEN(ppszTypeName));
}
const char* CInv::GetCommand() const
@@ -310,3 +147,4 @@ void CInv::print() const
{
printf("CInv(%s)\n", ToString().c_str());
}

View File

@@ -1,5 +1,5 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2011 The Bitcoin developers
// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
@@ -11,6 +11,7 @@
#define __INCLUDED_PROTOCOL_H__
#include "serialize.h"
#include "netbase.h"
#include <string>
#include "uint256.h"
@@ -20,15 +21,15 @@ static inline unsigned short GetDefaultPort(const bool testnet = fTestNet)
return testnet ? 18333 : 8333;
}
//
// Message header
// (4) message start
// (12) command
// (4) size
// (4) checksum
extern unsigned char pchMessageStart[4];
/** Message header.
* (4) message start.
* (12) command.
* (4) size.
* (4) checksum.
*/
class CMessageHeader
{
public:
@@ -43,7 +44,6 @@ class CMessageHeader
READWRITE(FLATDATA(pchMessageStart));
READWRITE(FLATDATA(pchCommand));
READWRITE(nMessageSize);
if (nVersion >= 209)
READWRITE(nChecksum);
)
@@ -56,71 +56,50 @@ class CMessageHeader
unsigned int nChecksum;
};
/** nServices flags */
enum
{
NODE_NETWORK = (1 << 0),
};
class CAddress
/** A CService with information about it as peer */
class CAddress : public CService
{
public:
CAddress();
CAddress(unsigned int ipIn, unsigned short portIn=0, uint64 nServicesIn=NODE_NETWORK);
explicit CAddress(const struct sockaddr_in& sockaddr, uint64 nServicesIn=NODE_NETWORK);
explicit CAddress(const char* pszIn, int portIn, bool fNameLookup = false, uint64 nServicesIn=NODE_NETWORK);
explicit CAddress(const char* pszIn, bool fNameLookup = false, uint64 nServicesIn=NODE_NETWORK);
explicit CAddress(std::string strIn, int portIn, bool fNameLookup = false, uint64 nServicesIn=NODE_NETWORK);
explicit CAddress(std::string strIn, bool fNameLookup = false, uint64 nServicesIn=NODE_NETWORK);
explicit CAddress(CService ipIn, uint64 nServicesIn=NODE_NETWORK);
void Init();
IMPLEMENT_SERIALIZE
(
CAddress* pthis = const_cast<CAddress*>(this);
CService* pip = (CService*)pthis;
if (fRead)
const_cast<CAddress*>(this)->Init();
pthis->Init();
if (nType & SER_DISK)
READWRITE(nVersion);
if ((nType & SER_DISK) || (nVersion >= 31402 && !(nType & SER_GETHASH)))
READWRITE(nTime);
READWRITE(nVersion);
if ((nType & SER_DISK) ||
(nVersion >= CADDR_TIME_VERSION && !(nType & SER_GETHASH)))
READWRITE(nTime);
READWRITE(nServices);
READWRITE(FLATDATA(pchReserved)); // for IPv6
READWRITE(ip);
READWRITE(port);
READWRITE(*pip);
)
friend bool operator==(const CAddress& a, const CAddress& b);
friend bool operator!=(const CAddress& a, const CAddress& b);
friend bool operator<(const CAddress& a, const CAddress& b);
std::vector<unsigned char> GetKey() const;
struct sockaddr_in GetSockAddr() const;
bool IsIPv4() const;
bool IsRFC1918() const;
bool IsRFC3927() const;
bool IsLocal() const;
bool IsRoutable() const;
bool IsValid() const;
unsigned char GetByte(int n) const;
std::string ToStringIPPort() const;
std::string ToStringIP() const;
std::string ToStringPort() const;
std::string ToString() const;
void print() const;
// TODO: make private (improves encapsulation)
public:
uint64 nServices;
unsigned char pchReserved[12];
unsigned int ip;
unsigned short port;
// disk and network only
unsigned int nTime;
// memory only
unsigned int nLastTry;
int64 nLastTry;
};
/** inv message data */
class CInv
{
public:

View File

@@ -2,12 +2,13 @@
#include "ui_aboutdialog.h"
#include "clientmodel.h"
#include "version.h"
AboutDialog::AboutDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::AboutDialog)
{
ui->setupUi(this);
}
void AboutDialog::setModel(ClientModel *model)

View File

@@ -2,13 +2,19 @@
#include "ui_addressbookpage.h"
#include "addresstablemodel.h"
#include "bitcoingui.h"
#include "editaddressdialog.h"
#include "csvmodelwriter.h"
#include "guiutil.h"
#include <QSortFilterProxyModel>
#include <QClipboard>
#include <QFileDialog>
#include <QMessageBox>
#include <QMenu>
#ifdef USE_QRCODE
#include "qrcodedialog.h"
#endif
AddressBookPage::AddressBookPage(Mode mode, Tabs tab, QWidget *parent) :
QDialog(parent),
@@ -25,6 +31,10 @@ AddressBookPage::AddressBookPage(Mode mode, Tabs tab, QWidget *parent) :
ui->deleteButton->setIcon(QIcon());
#endif
#ifndef USE_QRCODE
ui->showQRCode->setVisible(false);
#endif
switch(mode)
{
case ForSending:
@@ -33,19 +43,44 @@ AddressBookPage::AddressBookPage(Mode mode, Tabs tab, QWidget *parent) :
ui->tableView->setFocus();
break;
case ForEditing:
ui->buttonBox->hide();
ui->buttonBox->setVisible(false);
break;
}
switch(tab)
{
case SendingTab:
ui->labelExplanation->hide();
ui->labelExplanation->setVisible(false);
ui->deleteButton->setVisible(true);
ui->signMessage->setVisible(false);
break;
case ReceivingTab:
ui->deleteButton->setVisible(false);
ui->signMessage->setVisible(true);
break;
}
ui->tableView->setTabKeyNavigation(false);
ui->tableView->setContextMenuPolicy(Qt::CustomContextMenu);
// Context menu actions
QAction *copyAddressAction = new QAction(tr("Copy address"), this);
QAction *copyLabelAction = new QAction(tr("Copy label"), this);
QAction *editAction = new QAction(tr("Edit"), this);
deleteAction = new QAction(tr("Delete"), this);
contextMenu = new QMenu();
contextMenu->addAction(copyAddressAction);
contextMenu->addAction(copyLabelAction);
contextMenu->addAction(editAction);
contextMenu->addAction(deleteAction);
connect(copyAddressAction, SIGNAL(triggered()), this, SLOT(on_copyToClipboard_clicked()));
connect(copyLabelAction, SIGNAL(triggered()), this, SLOT(onCopyLabelAction()));
connect(editAction, SIGNAL(triggered()), this, SLOT(onEditAction()));
connect(deleteAction, SIGNAL(triggered()), this, SLOT(on_deleteButton_clicked()));
connect(ui->tableView, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextualMenu(QPoint)));
// Pass through accept action from button box
connect(ui->buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
}
@@ -59,8 +94,6 @@ void AddressBookPage::setModel(AddressTableModel *model)
this->model = model;
if(!model)
return;
// Refresh list from core
model->updateList();
proxyModel = new QSortFilterProxyModel(this);
proxyModel->setSourceModel(model);
@@ -100,18 +133,48 @@ void AddressBookPage::setModel(AddressTableModel *model)
void AddressBookPage::on_copyToClipboard_clicked()
{
// Copy currently selected address to clipboard
// (or nothing, if nothing selected)
QTableView *table = ui->tableView;
if(!table->selectionModel())
GUIUtil::copyEntryData(ui->tableView, AddressTableModel::Address);
}
void AddressBookPage::onCopyLabelAction()
{
GUIUtil::copyEntryData(ui->tableView, AddressTableModel::Label);
}
void AddressBookPage::onEditAction()
{
if(!ui->tableView->selectionModel())
return;
QModelIndexList indexes = ui->tableView->selectionModel()->selectedRows();
if(indexes.isEmpty())
return;
EditAddressDialog dlg(
tab == SendingTab ?
EditAddressDialog::EditSendingAddress :
EditAddressDialog::EditReceivingAddress);
dlg.setModel(model);
QModelIndex origIndex = proxyModel->mapToSource(indexes.at(0));
dlg.loadRow(origIndex.row());
dlg.exec();
}
void AddressBookPage::on_signMessage_clicked()
{
QTableView *table = ui->tableView;
QModelIndexList indexes = table->selectionModel()->selectedRows(AddressTableModel::Address);
QString addr;
foreach (QModelIndex index, indexes)
{
QVariant address = index.data();
QApplication::clipboard()->setText(address.toString());
addr = address.toString();
}
QObject *qoGUI = parent()->parent();
BitcoinGUI *gui = qobject_cast<BitcoinGUI *>(qoGUI);
if (gui)
gui->gotoMessagePage(addr);
}
void AddressBookPage::on_newAddressButton_clicked()
@@ -162,18 +225,31 @@ void AddressBookPage::selectionChanged()
switch(tab)
{
case SendingTab:
// In sending tab, allow deletion of selection
ui->deleteButton->setEnabled(true);
ui->deleteButton->setVisible(true);
deleteAction->setEnabled(true);
ui->signMessage->setEnabled(false);
ui->signMessage->setVisible(false);
break;
case ReceivingTab:
// Deleting receiving addresses, however, is not allowed
ui->deleteButton->setEnabled(false);
ui->deleteButton->setVisible(false);
deleteAction->setEnabled(false);
ui->signMessage->setEnabled(true);
ui->signMessage->setVisible(true);
break;
}
ui->copyToClipboard->setEnabled(true);
ui->showQRCode->setEnabled(true);
}
else
{
ui->deleteButton->setEnabled(false);
ui->showQRCode->setEnabled(false);
ui->copyToClipboard->setEnabled(false);
ui->signMessage->setEnabled(false);
}
}
@@ -197,6 +273,7 @@ void AddressBookPage::done(int retval)
if(returnValue.isEmpty())
{
// If no address entry selected, return rejected
retval = Rejected;
}
@@ -206,10 +283,9 @@ void AddressBookPage::done(int retval)
void AddressBookPage::exportClicked()
{
// CSV is currently the only supported format
QString filename = QFileDialog::getSaveFileName(
QString filename = GUIUtil::getSaveFileName(
this,
tr("Export Address Book Data"),
QDir::currentPath(),
tr("Export Address Book Data"), QString(),
tr("Comma separated file (*.csv)"));
if (filename.isNull()) return;
@@ -227,3 +303,28 @@ void AddressBookPage::exportClicked()
QMessageBox::Abort, QMessageBox::Abort);
}
}
void AddressBookPage::on_showQRCode_clicked()
{
#ifdef USE_QRCODE
QTableView *table = ui->tableView;
QModelIndexList indexes = table->selectionModel()->selectedRows(AddressTableModel::Address);
foreach (QModelIndex index, indexes)
{
QString address = index.data().toString(), label = index.sibling(index.row(), 0).data(Qt::EditRole).toString();
QRCodeDialog *dialog = new QRCodeDialog(address, label, tab == ReceivingTab, this);
dialog->show();
}
#endif
}
void AddressBookPage::contextualMenu(const QPoint &point)
{
QModelIndex index = ui->tableView->indexAt(point);
if(index.isValid())
{
contextMenu->exec(QCursor::pos());
}
}

View File

@@ -12,6 +12,7 @@ QT_BEGIN_NAMESPACE
class QTableView;
class QItemSelection;
class QSortFilterProxyModel;
class QMenu;
QT_END_NAMESPACE
/** Widget that shows a list of sending or receiving addresses.
@@ -48,12 +49,24 @@ private:
Tabs tab;
QString returnValue;
QSortFilterProxyModel *proxyModel;
QMenu *contextMenu;
QAction *deleteAction;
private slots:
void on_deleteButton_clicked();
void on_newAddressButton_clicked();
/** Copy address of currently selected address entry to clipboard */
void on_copyToClipboard_clicked();
void on_signMessage_clicked();
void selectionChanged();
void on_showQRCode_clicked();
/** Spawn contextual menu (right mouse menu) for address book entry */
void contextualMenu(const QPoint &point);
/** Copy label of currently selected address entry to clipboard */
void onCopyLabelAction();
/** Edit currently selected address entry */
void onEditAction();
};
#endif // ADDRESSBOOKDIALOG_H

View File

@@ -2,7 +2,7 @@
#include "guiutil.h"
#include "walletmodel.h"
#include "headers.h"
#include "wallet.h"
#include <QFont>
#include <QColor>
@@ -27,8 +27,9 @@ struct AddressTableEntry
};
// Private implementation
struct AddressTablePriv
class AddressTablePriv
{
public:
CWallet *wallet;
QList<AddressTableEntry> cachedAddressTable;
@@ -39,8 +40,8 @@ struct AddressTablePriv
{
cachedAddressTable.clear();
CRITICAL_BLOCK(wallet->cs_wallet)
{
LOCK(wallet->cs_wallet);
BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, std::string)& item, wallet->mapAddressBook)
{
const CBitcoinAddress& address = item.first;
@@ -169,8 +170,8 @@ bool AddressTableModel::setData(const QModelIndex & index, const QVariant & valu
// Double-check that we're not overwriting a receiving address
if(rec->type == AddressTableEntry::Sending)
{
CRITICAL_BLOCK(wallet->cs_wallet)
{
LOCK(wallet->cs_wallet);
// Remove old entry
wallet->DelAddressBookName(rec->address.toStdString());
// Add new entry with new address
@@ -231,7 +232,7 @@ QModelIndex AddressTableModel::index(int row, int column, const QModelIndex & pa
}
}
void AddressTableModel::updateList()
void AddressTableModel::update()
{
// Update address book model from Bitcoin core
beginResetModel();
@@ -254,8 +255,8 @@ QString AddressTableModel::addRow(const QString &type, const QString &label, con
return QString();
}
// Check for duplicate addresses
CRITICAL_BLOCK(wallet->cs_wallet)
{
LOCK(wallet->cs_wallet);
if(wallet->mapAddressBook.count(strAddress))
{
editStatus = DUPLICATE_ADDRESS;
@@ -285,10 +286,11 @@ QString AddressTableModel::addRow(const QString &type, const QString &label, con
{
return QString();
}
// Add entry and update list
CRITICAL_BLOCK(wallet->cs_wallet)
// Add entry
{
LOCK(wallet->cs_wallet);
wallet->SetAddressBookName(strAddress, strLabel);
updateList();
}
return QString::fromStdString(strAddress);
}
@@ -302,25 +304,19 @@ bool AddressTableModel::removeRows(int row, int count, const QModelIndex & paren
// Also refuse to remove receiving addresses.
return false;
}
CRITICAL_BLOCK(wallet->cs_wallet)
{
LOCK(wallet->cs_wallet);
wallet->DelAddressBookName(rec->address.toStdString());
}
updateList();
return true;
}
void AddressTableModel::update()
{
}
/* Look up label for address in address book, if not found return empty string.
*/
QString AddressTableModel::labelForAddress(const QString &address) const
{
CRITICAL_BLOCK(wallet->cs_wallet)
{
LOCK(wallet->cs_wallet);
CBitcoinAddress address_parsed(address.toStdString());
std::map<CBitcoinAddress, std::string>::iterator mi = wallet->mapAddressBook.find(address_parsed);
if (mi != wallet->mapAddressBook.end())

View File

@@ -56,10 +56,6 @@ public:
*/
QString addRow(const QString &type, const QString &label, const QString &address);
/* Update address list from core. Invalidates any indices.
*/
void updateList();
/* Look up label for address in address book, if not found return empty string.
*/
QString labelForAddress(const QString &address) const;
@@ -82,6 +78,8 @@ signals:
void defaultAddressChanged(const QString &address);
public slots:
/* Update address list from core. Invalidates any indices.
*/
void update();
};

View File

@@ -1,52 +1,55 @@
/*
* W.J. van der Laan 2011
* W.J. van der Laan 2011-2012
*/
#include "bitcoingui.h"
#include "clientmodel.h"
#include "walletmodel.h"
#include "optionsmodel.h"
#include "guiutil.h"
#include "headers.h"
#include "init.h"
#include "ui_interface.h"
#include "qtipcserver.h"
#include <QApplication>
#include <QMessageBox>
#include <QThread>
#include <QTextCodec>
#include <QLocale>
#include <QTranslator>
#include <QSplashScreen>
#include <QLibraryInfo>
#include <boost/interprocess/ipc/message_queue.hpp>
#if defined(BITCOIN_NEED_QT_PLUGINS) && !defined(_BITCOIN_QT_PLUGINS_INCLUDED)
#define _BITCOIN_QT_PLUGINS_INCLUDED
#define __INSURE__
#include <QtPlugin>
Q_IMPORT_PLUGIN(qcncodecs)
Q_IMPORT_PLUGIN(qjpcodecs)
Q_IMPORT_PLUGIN(qtwcodecs)
Q_IMPORT_PLUGIN(qkrcodecs)
Q_IMPORT_PLUGIN(qtaccessiblewidgets)
#endif
// Need a global reference for the notifications to find the GUI
BitcoinGUI *guiref;
QSplashScreen *splashref;
static BitcoinGUI *guiref;
static QSplashScreen *splashref;
static WalletModel *walletmodel;
static ClientModel *clientmodel;
int MyMessageBox(const std::string& message, const std::string& caption, int style, wxWindow* parent, int x, int y)
{
// Message from main thread
if(guiref)
{
guiref->error(QString::fromStdString(caption),
QString::fromStdString(message));
}
else
{
QMessageBox::critical(0, QString::fromStdString(caption),
QString::fromStdString(message),
QMessageBox::Ok, QMessageBox::Ok);
}
return 4;
}
int ThreadSafeMessageBox(const std::string& message, const std::string& caption, int style, wxWindow* parent, int x, int y)
int ThreadSafeMessageBox(const std::string& message, const std::string& caption, int style)
{
// Message from network thread
if(guiref)
{
QMetaObject::invokeMethod(guiref, "error", Qt::QueuedConnection,
bool modal = (style & wxMODAL);
// in case of modal message, use blocking connection to wait for user to click OK
QMetaObject::invokeMethod(guiref, "error",
modal ? GUIUtil::blockingGUIThreadConnection() : Qt::QueuedConnection,
Q_ARG(QString, QString::fromStdString(caption)),
Q_ARG(QString, QString::fromStdString(message)));
Q_ARG(QString, QString::fromStdString(message)),
Q_ARG(bool, modal));
}
else
{
@@ -56,7 +59,7 @@ int ThreadSafeMessageBox(const std::string& message, const std::string& caption,
return 4;
}
bool ThreadSafeAskFee(int64 nFeeRequired, const std::string& strCaption, wxWindow* parent)
bool ThreadSafeAskFee(int64 nFeeRequired, const std::string& strCaption)
{
if(!guiref)
return false;
@@ -64,35 +67,34 @@ bool ThreadSafeAskFee(int64 nFeeRequired, const std::string& strCaption, wxWindo
return true;
bool payFee = false;
// Call slot on GUI thread.
// If called from another thread, use a blocking QueuedConnection.
Qt::ConnectionType connectionType = Qt::DirectConnection;
if(QThread::currentThread() != QCoreApplication::instance()->thread())
{
connectionType = Qt::BlockingQueuedConnection;
}
QMetaObject::invokeMethod(guiref, "askFee", connectionType,
QMetaObject::invokeMethod(guiref, "askFee", GUIUtil::blockingGUIThreadConnection(),
Q_ARG(qint64, nFeeRequired),
Q_ARG(bool*, &payFee));
return payFee;
}
void CalledSetStatusBar(const std::string& strText, int nField)
void ThreadSafeHandleURI(const std::string& strURI)
{
// Only used for built-in mining, which is disabled, simple ignore
}
if(!guiref)
return;
void UIThreadCall(boost::function0<void> fn)
{
// Only used for built-in mining, which is disabled, simple ignore
QMetaObject::invokeMethod(guiref, "handleURI", GUIUtil::blockingGUIThreadConnection(),
Q_ARG(QString, QString::fromStdString(strURI)));
}
void MainFrameRepaint()
{
if(guiref)
QMetaObject::invokeMethod(guiref, "refreshStatusBar", Qt::QueuedConnection);
if(clientmodel)
QMetaObject::invokeMethod(clientmodel, "update", Qt::QueuedConnection);
if(walletmodel)
QMetaObject::invokeMethod(walletmodel, "update", Qt::QueuedConnection);
}
void AddressBookRepaint()
{
if(walletmodel)
QMetaObject::invokeMethod(walletmodel, "updateAddressList", Qt::QueuedConnection);
}
void InitMessage(const std::string &message)
@@ -104,6 +106,11 @@ void InitMessage(const std::string &message)
}
}
void QueueShutdown()
{
QMetaObject::invokeMethod(QCoreApplication::instance(), "quit", Qt::QueuedConnection);
}
/*
Translate string to current locale using Qt.
*/
@@ -112,19 +119,81 @@ std::string _(const char* psz)
return QCoreApplication::translate("bitcoin-core", psz).toStdString();
}
/* Handle runaway exceptions. Shows a message box with the problem and quits the program.
*/
static void handleRunawayException(std::exception *e)
{
PrintExceptionContinue(e, "Runaway exception");
QMessageBox::critical(0, "Runaway exception", BitcoinGUI::tr("A fatal error occured. Bitcoin can no longer continue safely and will quit.") + QString("\n\n") + QString::fromStdString(strMiscWarning));
exit(1);
}
#ifdef WIN32
#define strncasecmp strnicmp
#endif
#ifndef BITCOIN_QT_TEST
int main(int argc, char *argv[])
{
#if !defined(MAC_OSX) && !defined(WIN32)
// TODO: implement qtipcserver.cpp for Mac and Windows
// Do this early as we don't want to bother initializing if we are just calling IPC
for (int i = 1; i < argc; i++)
{
if (strlen(argv[i]) > 7 && strncasecmp(argv[i], "bitcoin:", 8) == 0)
{
const char *strURI = argv[i];
try {
boost::interprocess::message_queue mq(boost::interprocess::open_only, BITCOINURI_QUEUE_NAME);
if(mq.try_send(strURI, strlen(strURI), 0))
exit(0);
else
break;
}
catch (boost::interprocess::interprocess_exception &ex) {
break;
}
}
}
#endif
// Internal string conversion is all UTF-8
QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8"));
QTextCodec::setCodecForCStrings(QTextCodec::codecForTr());
Q_INIT_RESOURCE(bitcoin);
QApplication app(argc, argv);
// Load language files for system locale:
// Command-line options take precedence:
ParseParameters(argc, argv);
// ... then bitcoin.conf:
if (!boost::filesystem::is_directory(GetDataDir(false)))
{
fprintf(stderr, "Error: Specified directory does not exist\n");
return 1;
}
ReadConfigFile(mapArgs, mapMultiArgs);
// Application identification (must be set before OptionsModel is initialized,
// as it is used to locate QSettings)
app.setOrganizationName("Bitcoin");
app.setOrganizationDomain("bitcoin.org");
if(GetBoolArg("-testnet")) // Separate UI settings for testnet
app.setApplicationName("Bitcoin-Qt-testnet");
else
app.setApplicationName("Bitcoin-Qt");
// ... then GUI settings:
OptionsModel optionsModel;
// Get desired locale ("en_US") from command line or system locale
QString lang_territory = QString::fromStdString(GetArg("-lang", QLocale::system().name().toStdString()));
// Load language files for configured locale:
// - First load the translator for the base language, without territory
// - Then load the more specific locale translator
QString lang_territory = QLocale::system().name(); // "en_US"
QString lang = lang_territory;
lang.truncate(lang_territory.lastIndexOf('_')); // "en"
QTranslator qtTranslatorBase, qtTranslator, translatorBase, translator;
@@ -144,12 +213,13 @@ int main(int argc, char *argv[])
if (!translator.isEmpty())
app.installTranslator(&translator);
app.setApplicationName(QApplication::translate("main", "Bitcoin-Qt"));
QSplashScreen splash(QPixmap(":/images/splash"), 0);
splash.show();
splash.setAutoFillBackground(true);
splashref = &splash;
if (GetBoolArg("-splash", true) && !GetBoolArg("-min"))
{
splash.show();
splash.setAutoFillBackground(true);
splashref = &splash;
}
app.processEvents();
@@ -157,18 +227,24 @@ int main(int argc, char *argv[])
try
{
BitcoinGUI window;
guiref = &window;
if(AppInit2(argc, argv))
{
{
// Put this in a block, so that BitcoinGUI is cleaned up properly before
// calling Shutdown() in case of exceptions.
BitcoinGUI window;
splash.finish(&window);
OptionsModel optionsModel(pwalletMain);
ClientModel clientModel(&optionsModel);
WalletModel walletModel(pwalletMain, &optionsModel);
// Put this in a block, so that the Model objects are cleaned up before
// calling Shutdown().
optionsModel.Upgrade(); // Must be done after AppInit2
if (splashref)
splash.finish(&window);
ClientModel clientModel(&optionsModel);
clientmodel = &clientModel;
WalletModel walletModel(pwalletMain, &optionsModel);
walletmodel = &walletModel;
guiref = &window;
window.setClientModel(&clientModel);
window.setWalletModel(&walletModel);
@@ -182,9 +258,34 @@ int main(int argc, char *argv[])
window.show();
}
// Place this here as guiref has to be defined if we dont want to lose URIs
ipcInit();
#if !defined(MAC_OSX) && !defined(WIN32)
// TODO: implement qtipcserver.cpp for Mac and Windows
// Check for URI in argv
for (int i = 1; i < argc; i++)
{
if (strlen(argv[i]) > 7 && strncasecmp(argv[i], "bitcoin:", 8) == 0)
{
const char *strURI = argv[i];
try {
boost::interprocess::message_queue mq(boost::interprocess::open_only, BITCOINURI_QUEUE_NAME);
mq.try_send(strURI, strlen(strURI), 0);
}
catch (boost::interprocess::interprocess_exception &ex) {
}
}
}
#endif
app.exec();
window.setClientModel(0);
window.setWalletModel(0);
guiref = 0;
clientmodel = 0;
walletmodel = 0;
}
Shutdown(NULL);
}
@@ -193,9 +294,10 @@ int main(int argc, char *argv[])
return 1;
}
} catch (std::exception& e) {
PrintException(&e, "Runaway exception");
handleRunawayException(&e);
} catch (...) {
PrintException(NULL, "Runaway exception");
handleRunawayException(NULL);
}
return 0;
}
#endif // BITCOIN_QT_TEST

View File

@@ -1,5 +1,5 @@
<RCC>
<qresource prefix="/icons" lang="edit">
<qresource prefix="/icons">
<file alias="bitcoin">res/icons/bitcoin.png</file>
<file alias="address-book">res/icons/address-book.png</file>
<file alias="quit">res/icons/quit.png</file>
@@ -37,26 +37,46 @@
<file alias="lock_closed">res/icons/lock_closed.png</file>
<file alias="lock_open">res/icons/lock_open.png</file>
<file alias="key">res/icons/key.png</file>
<file alias="filesave">res/icons/filesave.png</file>
</qresource>
<qresource prefix="/images">
<file alias="about">res/images/about.png</file>
<file alias="splash">res/images/splash2.jpg</file>
<file alias="qrcode">res/images/qrcode.png</file>
</qresource>
<qresource prefix="/movies">
<file alias="update_spinner">res/movies/update_spinner.mng</file>
</qresource>
<qresource prefix="/translations">
<file alias="ca_ES">locale/bitcoin_ca_ES.qm</file>
<file alias="cs">locale/bitcoin_cs.qm</file>
<file alias="da">locale/bitcoin_da.qm</file>
<file alias="de">locale/bitcoin_de.qm</file>
<file alias="en">locale/bitcoin_en.qm</file>
<file alias="es">locale/bitcoin_es.qm</file>
<file alias="es_CL">locale/bitcoin_es_CL.qm</file>
<file alias="es">locale/bitcoin_es.qm</file>
<file alias="et">locale/bitcoin_et.qm</file>
<file alias="eu_ES">locale/bitcoin_eu_ES.qm</file>
<file alias="fa_IR">locale/bitcoin_fa_IR.qm</file>
<file alias="fa">locale/bitcoin_fa.qm</file>
<file alias="fi">locale/bitcoin_fi.qm</file>
<file alias="fr_CA">locale/bitcoin_fr_CA.qm</file>
<file alias="fr_FR">locale/bitcoin_fr_FR.qm</file>
<file alias="he">locale/bitcoin_he.qm</file>
<file alias="hr">locale/bitcoin_hr.qm</file>
<file alias="hu">locale/bitcoin_hu.qm</file>
<file alias="it">locale/bitcoin_it.qm</file>
<file alias="lt">locale/bitcoin_lt.qm</file>
<file alias="nb">locale/bitcoin_nb.qm</file>
<file alias="nl">locale/bitcoin_nl.qm</file>
<file alias="pl">locale/bitcoin_pl.qm</file>
<file alias="pt_BR">locale/bitcoin_pt_BR.qm</file>
<file alias="ro_RO">locale/bitcoin_ro_RO.qm</file>
<file alias="ru">locale/bitcoin_ru.qm</file>
<file alias="sk">locale/bitcoin_sk.qm</file>
<file alias="sr">locale/bitcoin_sr.qm</file>
<file alias="sv">locale/bitcoin_sv.qm</file>
<file alias="tr">locale/bitcoin_tr.qm</file>
<file alias="uk">locale/bitcoin_uk.qm</file>
<file alias="zh_CN">locale/bitcoin_zh_CN.qm</file>
<file alias="zh_TW">locale/bitcoin_zh_TW.qm</file>

View File

@@ -14,7 +14,7 @@ public:
State validate(QString &input, int &pos) const;
static const int MaxAddressLength = 34;
static const int MaxAddressLength = 35;
signals:
public slots:

View File

@@ -22,6 +22,7 @@ BitcoinAmountField::BitcoinAmountField(QWidget *parent):
amount->setDecimals(8);
amount->installEventFilter(this);
amount->setMaximumWidth(170);
amount->setSingleStep(0.001);
QHBoxLayout *layout = new QHBoxLayout(this);
layout->addWidget(amount);

View File

@@ -1,13 +1,14 @@
/*
* Qt4 bitcoin GUI.
*
* W.J. van der Laan 2011
* The Bitcoin Developers 2011
* W.J. van der Laan 20011-2012
* The Bitcoin Developers 20011-2012
*/
#include "bitcoingui.h"
#include "transactiontablemodel.h"
#include "addressbookpage.h"
#include "sendcoinsdialog.h"
#include "messagepage.h"
#include "optionsdialog.h"
#include "aboutdialog.h"
#include "clientmodel.h"
@@ -22,6 +23,7 @@
#include "guiconstants.h"
#include "askpassphrasedialog.h"
#include "notificator.h"
#include "guiutil.h"
#ifdef Q_WS_MAC
#include "macdockiconhandler.h"
@@ -45,6 +47,9 @@
#include <QStackedWidget>
#include <QDateTime>
#include <QMovie>
#include <QFileDialog>
#include <QDesktopServices>
#include <QTimer>
#include <QDragEnterEvent>
#include <QUrl>
@@ -57,6 +62,7 @@ BitcoinGUI::BitcoinGUI(QWidget *parent):
walletModel(0),
encryptWalletAction(0),
changePassphraseAction(0),
aboutQtAction(0),
trayIcon(0),
notificator(0)
{
@@ -98,12 +104,17 @@ BitcoinGUI::BitcoinGUI(QWidget *parent):
sendCoinsPage = new SendCoinsDialog(this);
messagePage = new MessagePage(this);
centralWidget = new QStackedWidget(this);
centralWidget->addWidget(overviewPage);
centralWidget->addWidget(transactionsPage);
centralWidget->addWidget(addressBookPage);
centralWidget->addWidget(receiveCoinsPage);
centralWidget->addWidget(sendCoinsPage);
#ifdef FIRST_CLASS_MESSAGING
centralWidget->addWidget(messagePage);
#endif
setCentralWidget(centralWidget);
// Create status bar
@@ -111,7 +122,6 @@ BitcoinGUI::BitcoinGUI(QWidget *parent):
// Status bar notification icons
QFrame *frameBlocks = new QFrame();
//frameBlocks->setFrameStyle(QFrame::Panel | QFrame::Sunken);
frameBlocks->setContentsMargins(0,0,0,0);
frameBlocks->setMinimumWidth(56);
frameBlocks->setMaximumWidth(56);
@@ -129,11 +139,11 @@ BitcoinGUI::BitcoinGUI(QWidget *parent):
frameBlocksLayout->addWidget(labelBlocksIcon);
frameBlocksLayout->addStretch();
// Progress bar for blocks download
progressBarLabel = new QLabel(tr("Synchronizing with network..."));
// Progress bar and label for blocks download
progressBarLabel = new QLabel();
progressBarLabel->setVisible(false);
progressBar = new QProgressBar();
progressBar->setToolTip(tr("Block chain synchronization in progress"));
progressBar->setAlignment(Qt::AlignCenter);
progressBar->setVisible(false);
statusBar()->addWidget(progressBarLabel);
@@ -153,6 +163,8 @@ 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
@@ -192,16 +204,25 @@ void BitcoinGUI::createActions()
sendCoinsAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_2));
tabGroup->addAction(sendCoinsAction);
connect(overviewAction, SIGNAL(triggered()), this, SLOT(show()));
messageAction = new QAction(QIcon(":/icons/edit"), tr("Sign &message"), this);
messageAction->setToolTip(tr("Prove you control an address"));
#ifdef FIRST_CLASS_MESSAGING
messageAction->setCheckable(true);
#endif
tabGroup->addAction(messageAction);
connect(overviewAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized()));
connect(overviewAction, SIGNAL(triggered()), this, SLOT(gotoOverviewPage()));
connect(historyAction, SIGNAL(triggered()), this, SLOT(show()));
connect(historyAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized()));
connect(historyAction, SIGNAL(triggered()), this, SLOT(gotoHistoryPage()));
connect(addressBookAction, SIGNAL(triggered()), this, SLOT(show()));
connect(addressBookAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized()));
connect(addressBookAction, SIGNAL(triggered()), this, SLOT(gotoAddressBookPage()));
connect(receiveCoinsAction, SIGNAL(triggered()), this, SLOT(show()));
connect(receiveCoinsAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized()));
connect(receiveCoinsAction, SIGNAL(triggered()), this, SLOT(gotoReceiveCoinsPage()));
connect(sendCoinsAction, SIGNAL(triggered()), this, SLOT(show()));
connect(sendCoinsAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized()));
connect(sendCoinsAction, SIGNAL(triggered()), this, SLOT(gotoSendCoinsPage()));
connect(messageAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized()));
connect(messageAction, SIGNAL(triggered()), this, SLOT(gotoMessagePage()));
quitAction = new QAction(QIcon(":/icons/quit"), tr("E&xit"), this);
quitAction->setToolTip(tr("Quit application"));
@@ -209,25 +230,32 @@ void BitcoinGUI::createActions()
quitAction->setMenuRole(QAction::QuitRole);
aboutAction = new QAction(QIcon(":/icons/bitcoin"), tr("&About %1").arg(qApp->applicationName()), this);
aboutAction->setToolTip(tr("Show information about Bitcoin"));
aboutAction->setMenuRole(QAction::AboutQtRole);
aboutAction->setMenuRole(QAction::AboutRole);
aboutQtAction = new QAction(tr("About &Qt"), this);
aboutQtAction->setToolTip(tr("Show information about Qt"));
aboutQtAction->setMenuRole(QAction::AboutQtRole);
optionsAction = new QAction(QIcon(":/icons/options"), tr("&Options..."), this);
optionsAction->setToolTip(tr("Modify configuration options for bitcoin"));
optionsAction->setMenuRole(QAction::PreferencesRole);
openBitcoinAction = new QAction(QIcon(":/icons/bitcoin"), tr("Open &Bitcoin"), this);
openBitcoinAction->setToolTip(tr("Show the Bitcoin window"));
toggleHideAction = new QAction(QIcon(":/icons/bitcoin"), tr("Show/Hide &Bitcoin"), this);
toggleHideAction->setToolTip(tr("Show or hide the Bitcoin window"));
exportAction = new QAction(QIcon(":/icons/export"), tr("&Export..."), this);
exportAction->setToolTip(tr("Export the current view to a file"));
exportAction->setToolTip(tr("Export the data in the current tab to a file"));
encryptWalletAction = new QAction(QIcon(":/icons/lock_closed"), tr("&Encrypt Wallet"), this);
encryptWalletAction->setToolTip(tr("Encrypt or decrypt wallet"));
encryptWalletAction->setCheckable(true);
backupWalletAction = new QAction(QIcon(":/icons/filesave"), tr("&Backup Wallet"), this);
backupWalletAction->setToolTip(tr("Backup wallet to another location"));
changePassphraseAction = new QAction(QIcon(":/icons/key"), tr("&Change Passphrase"), this);
changePassphraseAction->setToolTip(tr("Change the passphrase used for wallet encryption"));
connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
connect(optionsAction, SIGNAL(triggered()), this, SLOT(optionsClicked()));
connect(aboutAction, SIGNAL(triggered()), this, SLOT(aboutClicked()));
connect(openBitcoinAction, SIGNAL(triggered()), this, SLOT(showNormal()));
connect(aboutQtAction, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
connect(toggleHideAction, SIGNAL(triggered()), this, SLOT(toggleHidden()));
connect(encryptWalletAction, SIGNAL(triggered(bool)), this, SLOT(encryptWallet(bool)));
connect(backupWalletAction, SIGNAL(triggered()), this, SLOT(backupWallet()));
connect(changePassphraseAction, SIGNAL(triggered()), this, SLOT(changePassphrase()));
}
@@ -243,6 +271,12 @@ void BitcoinGUI::createMenuBar()
// Configure the menus
QMenu *file = appMenuBar->addMenu(tr("&File"));
file->addAction(backupWalletAction);
file->addAction(exportAction);
#ifndef FIRST_CLASS_MESSAGING
file->addAction(messageAction);
#endif
file->addSeparator();
file->addAction(quitAction);
QMenu *settings = appMenuBar->addMenu(tr("&Settings"));
@@ -253,6 +287,7 @@ void BitcoinGUI::createMenuBar()
QMenu *help = appMenuBar->addMenu(tr("&Help"));
help->addAction(aboutAction);
help->addAction(aboutQtAction);
}
void BitcoinGUI::createToolBars()
@@ -264,6 +299,9 @@ void BitcoinGUI::createToolBars()
toolbar->addAction(receiveCoinsAction);
toolbar->addAction(historyAction);
toolbar->addAction(addressBookAction);
#ifdef FIRST_CLASS_MESSAGING
toolbar->addAction(messageAction);
#endif
QToolBar *toolbar2 = addToolBar(tr("Actions toolbar"));
toolbar2->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
@@ -299,7 +337,7 @@ void BitcoinGUI::setClientModel(ClientModel *clientModel)
connect(clientModel, SIGNAL(numBlocksChanged(int)), this, SLOT(setNumBlocks(int)));
// Report errors from network/worker thread
connect(clientModel, SIGNAL(error(QString,QString)), this, SLOT(error(QString,QString)));
connect(clientModel, SIGNAL(error(QString,QString, bool)), this, SLOT(error(QString,QString,bool)));
}
}
@@ -309,7 +347,7 @@ void BitcoinGUI::setWalletModel(WalletModel *walletModel)
if(walletModel)
{
// Report errors from wallet thread
connect(walletModel, SIGNAL(error(QString,QString)), this, SLOT(error(QString,QString)));
connect(walletModel, SIGNAL(error(QString,QString,bool)), this, SLOT(error(QString,QString,bool)));
// Put transaction list in tabs
transactionView->setModel(walletModel);
@@ -318,6 +356,7 @@ void BitcoinGUI::setWalletModel(WalletModel *walletModel)
addressBookPage->setModel(walletModel->getAddressTableModel());
receiveCoinsPage->setModel(walletModel->getAddressTableModel());
sendCoinsPage->setModel(walletModel);
messagePage->setModel(walletModel);
setEncryptionStatus(walletModel->getEncryptionStatus());
connect(walletModel, SIGNAL(encryptionStatusChanged(int)), this, SLOT(setEncryptionStatus(int)));
@@ -338,7 +377,7 @@ void BitcoinGUI::createTrayIcon()
trayIcon = new QSystemTrayIcon(this);
trayIconMenu = new QMenu(this);
trayIcon->setContextMenu(trayIconMenu);
trayIcon->setToolTip("Bitcoin client");
trayIcon->setToolTip(tr("Bitcoin client"));
trayIcon->setIcon(QIcon(":/icons/toolbar"));
connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
this, SLOT(trayIconActivated(QSystemTrayIcon::ActivationReason)));
@@ -346,13 +385,17 @@ 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()), openBitcoinAction, SLOT(trigger()));
connect(dockIconHandler, SIGNAL(dockIconClicked()), toggleHideAction, SLOT(trigger()));
trayIconMenu = dockIconHandler->dockMenu();
#endif
// Configuration of the tray icon (or dock icon) icon menu
trayIconMenu->addAction(openBitcoinAction);
trayIconMenu->addAction(toggleHideAction);
trayIconMenu->addSeparator();
trayIconMenu->addAction(messageAction);
#ifndef FIRST_CLASS_MESSAGING
trayIconMenu->addSeparator();
#endif
trayIconMenu->addAction(receiveCoinsAction);
trayIconMenu->addAction(sendCoinsAction);
trayIconMenu->addSeparator();
@@ -370,13 +413,34 @@ void BitcoinGUI::trayIconActivated(QSystemTrayIcon::ActivationReason reason)
{
if(reason == QSystemTrayIcon::Trigger)
{
// Click on system tray icon triggers "open bitcoin"
openBitcoinAction->trigger();
// Click on system tray icon triggers "show/hide bitcoin"
toggleHideAction->trigger();
}
}
#endif
void BitcoinGUI::toggleHidden()
{
// activateWindow() (sometimes) helps with keyboard focus on Windows
if (isHidden())
{
show();
activateWindow();
}
else if (isMinimized())
{
showNormal();
activateWindow();
}
else if (GUIUtil::isObscured(this))
{
raise();
activateWindow();
}
else
hide();
}
void BitcoinGUI::optionsClicked()
{
if(!clientModel || !clientModel->getOptionsModel())
@@ -410,21 +474,31 @@ void BitcoinGUI::setNumConnections(int count)
void BitcoinGUI::setNumBlocks(int count)
{
if(!clientModel)
// don't show / hide progressBar and it's label if we have no connection(s) to the network
if (!clientModel || clientModel->getNumConnections() == 0)
{
progressBarLabel->setVisible(false);
progressBar->setVisible(false);
return;
int initTotal = clientModel->getNumBlocksAtStartup();
int total = clientModel->getNumBlocksOfPeers();
}
int nTotalBlocks = clientModel->getNumBlocksOfPeers();
QString tooltip;
if(count < total)
if(count < nTotalBlocks)
{
int nRemainingBlocks = nTotalBlocks - count;
float nPercentageDone = count / (nTotalBlocks * 0.01f);
if (clientModel->getStatusBarWarnings() == "")
{
progressBarLabel->setVisible(true);
progressBarLabel->setText(tr("Synchronizing with network..."));
progressBarLabel->setVisible(true);
progressBar->setFormat(tr("~%n block(s) remaining", "", nRemainingBlocks));
progressBar->setMaximum(nTotalBlocks);
progressBar->setValue(count);
progressBar->setVisible(true);
progressBar->setMaximum(total - initTotal);
progressBar->setValue(count - initTotal);
}
else
{
@@ -432,7 +506,7 @@ void BitcoinGUI::setNumBlocks(int count)
progressBarLabel->setVisible(true);
progressBar->setVisible(false);
}
tooltip = tr("Downloaded %1 of %2 blocks of transaction history.").arg(count).arg(total);
tooltip = tr("Downloaded %1 of %2 blocks of transaction history (%3% done).").arg(count).arg(nTotalBlocks).arg(nPercentageDone, 0, 'f', 2);
}
else
{
@@ -453,7 +527,11 @@ void BitcoinGUI::setNumBlocks(int count)
QString text;
// Represent time from last generated block in human readable text
if(secs < 60)
if(secs <= 0)
{
// Fully up to date. Leave text empty.
}
else if(secs < 60)
{
text = tr("%n second(s) ago","",secs);
}
@@ -471,10 +549,10 @@ void BitcoinGUI::setNumBlocks(int count)
}
// Set icon state: spinning if catching up, tick otherwise
if(secs < 30*60)
if(secs < 90*60 && count >= nTotalBlocks)
{
tooltip = tr("Up to date") + QString("\n") + tooltip;
labelBlocksIcon->setPixmap(QIcon(":/icons/synced").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE));
tooltip = tr("Up to date") + QString(".\n") + tooltip;
labelBlocksIcon->setPixmap(QIcon(":/icons/synced").pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE));
}
else
{
@@ -483,54 +561,45 @@ void BitcoinGUI::setNumBlocks(int count)
syncIconMovie->start();
}
tooltip += QString("\n");
tooltip += tr("Last received block was generated %1.").arg(text);
if(!text.isEmpty())
{
tooltip += QString("\n");
tooltip += tr("Last received block was generated %1.").arg(text);
}
labelBlocksIcon->setToolTip(tooltip);
progressBarLabel->setToolTip(tooltip);
progressBar->setToolTip(tooltip);
}
void BitcoinGUI::refreshStatusBar()
{
/* Might display multiple times in the case of multiple alerts
static QString prevStatusBar;
QString newStatusBar = clientModel->getStatusBarWarnings();
if (prevStatusBar != newStatusBar)
{
prevStatusBar = newStatusBar;
error(tr("Network Alert"), newStatusBar);
}*/
setNumBlocks(clientModel->getNumBlocks());
}
void BitcoinGUI::error(const QString &title, const QString &message)
void BitcoinGUI::error(const QString &title, const QString &message, bool modal)
{
// Report errors from network/worker thread
notificator->notify(Notificator::Critical, title, message);
if(modal)
{
QMessageBox::critical(this, title, message, QMessageBox::Ok, QMessageBox::Ok);
} else {
notificator->notify(Notificator::Critical, title, message);
}
}
void BitcoinGUI::changeEvent(QEvent *e)
{
QMainWindow::changeEvent(e);
#ifndef Q_WS_MAC // Ignored on Mac
if(e->type() == QEvent::WindowStateChange)
{
if(clientModel && clientModel->getOptionsModel()->getMinimizeToTray())
{
if(isMinimized())
QWindowStateChangeEvent *wsevt = static_cast<QWindowStateChangeEvent*>(e);
if(!(wsevt->oldState() & Qt::WindowMinimized) && isMinimized())
{
hide();
QTimer::singleShot(0, this, SLOT(hide()));
e->ignore();
}
else
{
show();
e->accept();
}
}
}
#endif
QMainWindow::changeEvent(e);
}
void BitcoinGUI::closeEvent(QCloseEvent *event)
@@ -644,9 +713,29 @@ void BitcoinGUI::gotoSendCoinsPage()
disconnect(exportAction, SIGNAL(triggered()), 0, 0);
}
void BitcoinGUI::gotoMessagePage()
{
#ifdef FIRST_CLASS_MESSAGING
messageAction->setChecked(true);
centralWidget->setCurrentWidget(messagePage);
exportAction->setEnabled(false);
disconnect(exportAction, SIGNAL(triggered()), 0, 0);
#else
messagePage->show();
messagePage->setFocus();
#endif
}
void BitcoinGUI::gotoMessagePage(QString addr)
{
gotoMessagePage();
messagePage->setAddress(addr);
}
void BitcoinGUI::dragEnterEvent(QDragEnterEvent *event)
{
// Accept only URLs
// Accept only URIs
if(event->mimeData()->hasUrls())
event->acceptProposedAction();
}
@@ -656,16 +745,27 @@ void BitcoinGUI::dropEvent(QDropEvent *event)
if(event->mimeData()->hasUrls())
{
gotoSendCoinsPage();
QList<QUrl> urls = event->mimeData()->urls();
foreach(const QUrl &url, urls)
QList<QUrl> uris = event->mimeData()->urls();
foreach(const QUrl &uri, uris)
{
sendCoinsPage->handleURL(&url);
sendCoinsPage->handleURI(uri.toString());
}
}
event->acceptProposedAction();
}
void BitcoinGUI::handleURI(QString strURI)
{
gotoSendCoinsPage();
sendCoinsPage->handleURI(strURI);
if(!isActiveWindow())
activateWindow();
showNormalIfMinimized();
}
void BitcoinGUI::setEncryptionStatus(int status)
{
switch(status)
@@ -707,6 +807,17 @@ void BitcoinGUI::encryptWallet(bool status)
setEncryptionStatus(walletModel->getEncryptionStatus());
}
void BitcoinGUI::backupWallet()
{
QString saveDir = QDesktopServices::storageLocation(QDesktopServices::DocumentsLocation);
QString filename = QFileDialog::getSaveFileName(this, tr("Backup Wallet"), saveDir, tr("Wallet Data (*.dat)"));
if(!filename.isEmpty()) {
if(!walletModel->backupWallet(filename)) {
QMessageBox::warning(this, tr("Backup Failed"), tr("There was an error trying to save the wallet data to the new location."));
}
}
}
void BitcoinGUI::changePassphrase()
{
AskPassphraseDialog dlg(AskPassphraseDialog::ChangePass, this);
@@ -726,3 +837,11 @@ void BitcoinGUI::unlockWallet()
dlg.exec();
}
}
void BitcoinGUI::showNormalIfMinimized()
{
if(!isVisible()) // Show, if hidden
show();
if(isMinimized()) // Unminimize, if minimized
showNormal();
}

View File

@@ -11,6 +11,7 @@ class TransactionView;
class OverviewPage;
class AddressBookPage;
class SendCoinsDialog;
class MessagePage;
class Notificator;
QT_BEGIN_NAMESPACE
@@ -62,6 +63,7 @@ private:
AddressBookPage *addressBookPage;
AddressBookPage *receiveCoinsPage;
SendCoinsDialog *sendCoinsPage;
MessagePage *messagePage;
QLabel *labelEncryptionIcon;
QLabel *labelConnectionsIcon;
@@ -75,13 +77,16 @@ private:
QAction *quitAction;
QAction *sendCoinsAction;
QAction *addressBookAction;
QAction *messageAction;
QAction *aboutAction;
QAction *receiveCoinsAction;
QAction *optionsAction;
QAction *openBitcoinAction;
QAction *toggleHideAction;
QAction *exportAction;
QAction *encryptWalletAction;
QAction *backupWalletAction;
QAction *changePassphraseAction;
QAction *aboutQtAction;
QSystemTrayIcon *trayIcon;
Notificator *notificator;
@@ -108,11 +113,9 @@ public slots:
@see WalletModel::EncryptionStatus
*/
void setEncryptionStatus(int status);
/** Set the status bar text if there are any warnings (removes sync progress bar if applicable) */
void refreshStatusBar();
/** Notify the user of an error in the network or transaction handling code. */
void error(const QString &title, const QString &message);
void error(const QString &title, const QString &message, bool modal);
/** Asks the user whether to pay the transaction fee or to cancel the transaction.
It is currently not possible to pass a return value to another thread through
BlockingQueuedConnection, so an indirected pointer is used.
@@ -122,6 +125,10 @@ public slots:
@param[out] payFee true to pay the fee, false to not pay the fee
*/
void askFee(qint64 nFeeRequired, bool *payFee);
void handleURI(QString strURI);
void gotoMessagePage();
void gotoMessagePage(QString);
private slots:
/** Switch to overview (home) page */
@@ -150,10 +157,17 @@ private slots:
void incomingTransaction(const QModelIndex & parent, int start, int end);
/** Encrypt the wallet */
void encryptWallet(bool status);
/** Backup the wallet */
void backupWallet();
/** Change encrypted wallet passphrase */
void changePassphrase();
/** Ask for pass phrase to unlock wallet temporarily */
void unlockWallet();
/** Show window if hidden, unminimize when minimized */
void showNormalIfMinimized();
/** Hide window if visible, show if hidden */
void toggleHidden();
};
#endif

View File

@@ -1,62 +1,96 @@
#include <QtGlobal>
// Automatically generated by extract_strings.py
static const char *bitcoin_strings[] = {QT_TRANSLATE_NOOP("bitcoin-core", "Bitcoin version"),
#ifdef __GNUC__
#define UNUSED __attribute__((unused))
#else
#define UNUSED
#endif
static const char UNUSED *bitcoin_strings[] = {QT_TRANSLATE_NOOP("bitcoin-core", ""
"Unable to bind to port %d on this computer. Bitcoin is probably already "
"running."),
QT_TRANSLATE_NOOP("bitcoin-core", "Warning: Disk space is low "),
QT_TRANSLATE_NOOP("bitcoin-core", "Bitcoin version"),
QT_TRANSLATE_NOOP("bitcoin-core", "Usage:"),
QT_TRANSLATE_NOOP("bitcoin-core", "Send command to -server or bitcoind\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "List commands\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Get help for a command\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Options:\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Specify configuration file (default: bitcoin.conf)\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Specify pid file (default: bitcoind.pid)\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Generate coins\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Don't generate coins\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Start minimized\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Specify data directory\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Specify connection timeout (in milliseconds)\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Connect through socks4 proxy\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Allow DNS lookups for addnode and connect\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Add a node to connect to\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Connect only to the specified node\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Don't accept connections from outside\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Threshold for disconnecting misbehaving peers (default: 100)\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Send command to -server or bitcoind"),
QT_TRANSLATE_NOOP("bitcoin-core", "List commands"),
QT_TRANSLATE_NOOP("bitcoin-core", "Get help for a command"),
QT_TRANSLATE_NOOP("bitcoin-core", "Options:"),
QT_TRANSLATE_NOOP("bitcoin-core", "Specify configuration file (default: bitcoin.conf)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Specify pid file (default: bitcoind.pid)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Generate coins"),
QT_TRANSLATE_NOOP("bitcoin-core", "Don't generate coins"),
QT_TRANSLATE_NOOP("bitcoin-core", "Start minimized"),
QT_TRANSLATE_NOOP("bitcoin-core", "Show splash screen on startup (default: 1)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Specify data directory"),
QT_TRANSLATE_NOOP("bitcoin-core", "Set database cache size in megabytes (default: 25)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Set database disk log size in megabytes (default: 100)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Specify connection timeout (in milliseconds)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Connect through socks4 proxy"),
QT_TRANSLATE_NOOP("bitcoin-core", "Allow DNS lookups for addnode and connect"),
QT_TRANSLATE_NOOP("bitcoin-core", "Listen for connections on <port> (default: 8333 or testnet: 18333)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Maintain at most <n> connections to peers (default: 125)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Add a node to connect to and attempt to keep the connection open"),
QT_TRANSLATE_NOOP("bitcoin-core", "Connect only to the specified node"),
QT_TRANSLATE_NOOP("bitcoin-core", "Find peers using internet relay chat (default: 0)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Accept connections from outside (default: 1)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Set language, for example \"de_DE\" (default: system locale)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Find peers using DNS lookup (default: 1)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Threshold for disconnecting misbehaving peers (default: 100)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Number of seconds to keep misbehaving peers from reconnecting (default: "
"86400)\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Don't attempt to use UPnP to map the listening port\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Attempt to use UPnP to map the listening port\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Fee per KB to add to transactions you send\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Accept command line and JSON-RPC commands\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Run in the background as a daemon and accept commands\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Use the test network\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Username for JSON-RPC connections\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Password for JSON-RPC connections\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Listen for JSON-RPC connections on <port> (default: 8332)\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Allow JSON-RPC connections from specified IP address\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Send commands to node running on <ip> (default: 127.0.0.1)\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Set key pool size to <n> (default: 100)\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Rescan the block chain for missing wallet transactions\n"),
"86400)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Maximum per-connection receive buffer, <n>*1000 bytes (default: 10000)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Maximum per-connection send buffer, <n>*1000 bytes (default: 10000)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Use Universal Plug and Play to map the listening port (default: 1)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Use Universal Plug and Play to map the listening port (default: 0)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Fee per KB to add to transactions you send"),
QT_TRANSLATE_NOOP("bitcoin-core", "Accept command line and JSON-RPC commands"),
QT_TRANSLATE_NOOP("bitcoin-core", "Run in the background as a daemon and accept commands"),
QT_TRANSLATE_NOOP("bitcoin-core", "Use the test network"),
QT_TRANSLATE_NOOP("bitcoin-core", "Output extra debugging information"),
QT_TRANSLATE_NOOP("bitcoin-core", "Prepend debug output with timestamp"),
QT_TRANSLATE_NOOP("bitcoin-core", "Send trace/debug info to console instead of debug.log file"),
QT_TRANSLATE_NOOP("bitcoin-core", "Send trace/debug info to debugger"),
QT_TRANSLATE_NOOP("bitcoin-core", "Username for JSON-RPC connections"),
QT_TRANSLATE_NOOP("bitcoin-core", "Password for JSON-RPC connections"),
QT_TRANSLATE_NOOP("bitcoin-core", "Listen for JSON-RPC connections on <port> (default: 8332)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Allow JSON-RPC connections from specified IP address"),
QT_TRANSLATE_NOOP("bitcoin-core", "Send commands to node running on <ip> (default: 127.0.0.1)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Execute command when the best block changes (%s in cmd is replaced by block "
"hash)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Upgrade wallet to latest format"),
QT_TRANSLATE_NOOP("bitcoin-core", "Set key pool size to <n> (default: 100)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Rescan the block chain for missing wallet transactions"),
QT_TRANSLATE_NOOP("bitcoin-core", "How many blocks to check at startup (default: 2500, 0 = all)"),
QT_TRANSLATE_NOOP("bitcoin-core", "How thorough the block verification is (0-6, default: 1)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"\n"
"SSL options: (see the Bitcoin Wiki for SSL setup instructions)\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Use OpenSSL (https) for JSON-RPC connections\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Server certificate file (default: server.cert)\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Server private key (default: server.pem)\n"),
"SSL options: (see the Bitcoin Wiki for SSL setup instructions)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Use OpenSSL (https) for JSON-RPC connections"),
QT_TRANSLATE_NOOP("bitcoin-core", "Server certificate file (default: server.cert)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Server private key (default: server.pem)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:"
"@STRENGTH)\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "This help message\n"),
"@STRENGTH)"),
QT_TRANSLATE_NOOP("bitcoin-core", "This help message"),
QT_TRANSLATE_NOOP("bitcoin-core", "Usage"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Cannot obtain a lock on data directory %s. Bitcoin is probably already "
"running."),
QT_TRANSLATE_NOOP("bitcoin-core", "Bitcoin"),
QT_TRANSLATE_NOOP("bitcoin-core", "Loading addresses..."),
QT_TRANSLATE_NOOP("bitcoin-core", "Error loading addr.dat \n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Error loading addr.dat"),
QT_TRANSLATE_NOOP("bitcoin-core", "Loading block index..."),
QT_TRANSLATE_NOOP("bitcoin-core", "Error loading blkindex.dat \n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Error loading blkindex.dat"),
QT_TRANSLATE_NOOP("bitcoin-core", "Loading wallet..."),
QT_TRANSLATE_NOOP("bitcoin-core", "Error loading wallet.dat: Wallet corrupted \n"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Error loading wallet.dat: Wallet requires newer version of Bitcoin \n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Error loading wallet.dat \n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Error loading wallet.dat: Wallet corrupted"),
QT_TRANSLATE_NOOP("bitcoin-core", "Error loading wallet.dat: Wallet requires newer version of Bitcoin"),
QT_TRANSLATE_NOOP("bitcoin-core", "Wallet needed to be rewritten: restart Bitcoin to complete"),
QT_TRANSLATE_NOOP("bitcoin-core", "Error loading wallet.dat"),
QT_TRANSLATE_NOOP("bitcoin-core", "Cannot downgrade wallet"),
QT_TRANSLATE_NOOP("bitcoin-core", "Cannot initialize keypool"),
QT_TRANSLATE_NOOP("bitcoin-core", "Cannot write default address"),
QT_TRANSLATE_NOOP("bitcoin-core", "Rescanning..."),
QT_TRANSLATE_NOOP("bitcoin-core", "Done loading"),
QT_TRANSLATE_NOOP("bitcoin-core", "Invalid -proxy address"),
@@ -65,12 +99,36 @@ QT_TRANSLATE_NOOP("bitcoin-core", ""
"Warning: -paytxfee is set very high. This is the transaction fee you will "
"pay if you send a transaction."),
QT_TRANSLATE_NOOP("bitcoin-core", "Error: CreateThread(StartNode) failed"),
QT_TRANSLATE_NOOP("bitcoin-core", "Warning: Disk space is low "),
QT_TRANSLATE_NOOP("bitcoin-core", "To use the %s option"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Unable to bind to port %d on this computer. Bitcoin is probably already "
"running."),
"%s, you must set a rpcpassword in the configuration file:\n"
" %s\n"
"It is recommended you use the following random password:\n"
"rpcuser=bitcoinrpc\n"
"rpcpassword=%s\n"
"(you do not need to remember this password)\n"
"If the file does not exist, create it with owner-readable-only file "
"permissions.\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Error"),
QT_TRANSLATE_NOOP("bitcoin-core", "An error occured while setting up the RPC port %i for listening: %s"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"You must set rpcpassword=<password> in the configuration file:\n"
"%s\n"
"If the file does not exist, create it with owner-readable-only file "
"permissions."),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Warning: Please check that your computer's date and time are correct. If "
"your clock is wrong Bitcoin will not work properly."),
QT_TRANSLATE_NOOP("bitcoin-core", "beta"),
QT_TRANSLATE_NOOP("bitcoin-core", "Error: Wallet locked, unable to create transaction "),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Error: This transaction requires a transaction fee of at least %s because of "
"its amount, complexity, or use of recently received funds "),
QT_TRANSLATE_NOOP("bitcoin-core", "Error: Transaction creation failed "),
QT_TRANSLATE_NOOP("bitcoin-core", "Sending..."),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Error: The transaction was rejected. This might happen if some of the coins "
"in your wallet were already spent, such as if you used a copy of wallet.dat "
"and coins were spent in the copy but not marked as spent here."),
QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount"),
QT_TRANSLATE_NOOP("bitcoin-core", "Insufficient funds"),
};

View File

@@ -4,21 +4,14 @@
#include "addresstablemodel.h"
#include "transactiontablemodel.h"
#include "headers.h"
#include "main.h"
#include <QTimer>
#include <QDateTime>
ClientModel::ClientModel(OptionsModel *optionsModel, QObject *parent) :
QObject(parent), optionsModel(optionsModel),
cachedNumConnections(0), cachedNumBlocks(0)
{
// Until signal notifications is built into the bitcoin core,
// simply update everything after polling using a timer.
QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(update()));
timer->start(MODEL_UPDATE_DELAY);
numBlocksAtStartup = -1;
}
@@ -47,14 +40,23 @@ void ClientModel::update()
{
int newNumConnections = getNumConnections();
int newNumBlocks = getNumBlocks();
QString newStatusBar = getStatusBarWarnings();
if(cachedNumConnections != newNumConnections)
emit numConnectionsChanged(newNumConnections);
if(cachedNumBlocks != newNumBlocks)
if(cachedNumBlocks != newNumBlocks || cachedStatusBar != newStatusBar)
{
// Simply emit a numBlocksChanged for now in case the status message changes,
// so that the view updates the status bar.
// TODO: It should send a notification.
// (However, this might generate looped notifications and needs to be thought through and tested carefully)
// error(tr("Network Alert"), newStatusBar);
emit numBlocksChanged(newNumBlocks);
}
cachedNumConnections = newNumConnections;
cachedNumBlocks = newNumBlocks;
cachedStatusBar = newStatusBar;
}
bool ClientModel::isTestNet() const
@@ -86,3 +88,8 @@ QString ClientModel::formatFullVersion() const
{
return QString::fromStdString(FormatFullVersion());
}
QString ClientModel::formatBuildDate() const
{
return QString::fromStdString(CLIENT_DATE);
}

View File

@@ -37,12 +37,14 @@ public:
QString getStatusBarWarnings() const;
QString formatFullVersion() const;
QString formatBuildDate() const;
private:
OptionsModel *optionsModel;
int cachedNumConnections;
int cachedNumBlocks;
QString cachedStatusBar;
int numBlocksAtStartup;
@@ -51,7 +53,7 @@ signals:
void numBlocksChanged(int count);
//! Asynchronous error notification
void error(const QString &title, const QString &message);
void error(const QString &title, const QString &message, bool modal);
public slots:

View File

@@ -6,7 +6,7 @@
CSVModelWriter::CSVModelWriter(const QString &filename, QObject *parent) :
QObject(parent),
filename(filename)
filename(filename), model(0)
{
}

View File

@@ -106,6 +106,9 @@ void EditAddressDialog::accept()
tr("New key generation failed."),
QMessageBox::Ok, QMessageBox::Ok);
return;
case AddressTableModel::OK:
// Failed with unknown reason. Just reject.
break;
}
return;

View File

@@ -52,6 +52,9 @@
<property name="text">
<string>&lt;b&gt;Bitcoin&lt;/b&gt; version</string>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item>
@@ -62,6 +65,9 @@
<property name="textFormat">
<enum>Qt::RichText</enum>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item>
@@ -82,7 +88,7 @@
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Copyright © 2009-2011 Bitcoin Developers
<string>Copyright © 2009-2012 Bitcoin Developers
This is experimental software.
@@ -93,6 +99,9 @@ This product includes software developed by the OpenSSL Project for use in the O
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item>

View File

@@ -79,6 +79,31 @@
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="showQRCode">
<property name="text">
<string>Show &amp;QR Code</string>
</property>
<property name="icon">
<iconset resource="../bitcoin.qrc">
<normaloff>:/images/qrcode</normaloff>:/images/qrcode</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="signMessage">
<property name="toolTip">
<string>Sign a message to prove you own this address</string>
</property>
<property name="text">
<string>&amp;Sign Message</string>
</property>
<property name="icon">
<iconset resource="../bitcoin.qrc">
<normaloff>:/icons/edit</normaloff>:/icons/edit</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="deleteButton">
<property name="toolTip">

170
src/qt/forms/messagepage.ui Normal file
View File

@@ -0,0 +1,170 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MessagePage</class>
<widget class="QWidget" name="MessagePage">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>627</width>
<height>380</height>
</rect>
</property>
<property name="windowTitle">
<string>Message</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="labelExplanation">
<property name="text">
<string>You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</string>
</property>
<property name="textFormat">
<enum>Qt::AutoText</enum>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="spacing">
<number>0</number>
</property>
<item>
<widget class="QValidatedLineEdit" name="signFrom">
<property name="toolTip">
<string>The address to sign the message with (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)</string>
</property>
<property name="maxLength">
<number>34</number>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="addressBookButton">
<property name="toolTip">
<string>Choose adress from address book</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../bitcoin.qrc">
<normaloff>:/icons/address-book</normaloff>:/icons/address-book</iconset>
</property>
<property name="shortcut">
<string>Alt+A</string>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
<property name="flat">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pasteButton">
<property name="toolTip">
<string>Paste address from clipboard</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../bitcoin.qrc">
<normaloff>:/icons/editpaste</normaloff>:/icons/editpaste</iconset>
</property>
<property name="shortcut">
<string>Alt+P</string>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QPlainTextEdit" name="message">
<property name="toolTip">
<string>Enter the message you want to sign here</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="signature">
<property name="font">
<font>
<italic>true</italic>
</font>
</property>
<property name="text">
<string>Click &quot;Sign Message&quot; to get signature</string>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="signMessage">
<property name="toolTip">
<string>Sign a message to prove you own this address</string>
</property>
<property name="text">
<string>&amp;Sign Message</string>
</property>
<property name="icon">
<iconset resource="../bitcoin.qrc">
<normaloff>:/icons/edit</normaloff>:/icons/edit</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="copyToClipboard">
<property name="toolTip">
<string>Copy the current signature to the system clipboard</string>
</property>
<property name="text">
<string>&amp;Copy to Clipboard</string>
</property>
<property name="icon">
<iconset resource="../bitcoin.qrc">
<normaloff>:/icons/editcopy</normaloff>:/icons/editcopy</iconset>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>QValidatedLineEdit</class>
<extends>QLineEdit</extends>
<header>qvalidatedlineedit.h</header>
</customwidget>
</customwidgets>
<resources>
<include location="../bitcoin.qrc"/>
</resources>
<connections/>
</ui>

View File

@@ -0,0 +1,216 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>QRCodeDialog</class>
<widget class="QDialog" name="QRCodeDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>320</width>
<height>404</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QLabel" name="lblQRCode">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>300</width>
<height>300</height>
</size>
</property>
<property name="text">
<string>QR Code</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QWidget" name="widget" native="true">
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QCheckBox" name="chkReqPayment">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>Request Payment</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="lblAmount">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Amount:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>lnReqAmount</cstring>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lnReqAmount">
<property name="enabled">
<bool>false</bool>
</property>
<property name="minimumSize">
<size>
<width>60</width>
<height>0</height>
</size>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lblBTC">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>BTC</string>
</property>
<property name="buddy">
<cstring>lnReqAmount</cstring>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="lblLabel">
<property name="text">
<string>Label:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>lnLabel</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="lnLabel">
<property name="minimumSize">
<size>
<width>100</width>
<height>0</height>
</size>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="lblMessage">
<property name="text">
<string>Message:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>lnMessage</cstring>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="lnMessage">
<property name="minimumSize">
<size>
<width>100</width>
<height>0</height>
</size>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="btnSaveAs">
<property name="text">
<string>&amp;Save As...</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>chkReqPayment</sender>
<signal>clicked(bool)</signal>
<receiver>lnReqAmount</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>92</x>
<y>285</y>
</hint>
<hint type="destinationlabel">
<x>98</x>
<y>311</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@@ -80,6 +80,9 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Remove all transaction fields</string>
</property>
<property name="text">
<string>Clear all</string>
</property>

Some files were not shown because too many files have changed in this diff Show More