At least one service that accepted zero-confirmation transactions
was vulnerable because an attacker could send a transaction
with a lock time far in the future, and then have plenty of time in
which to get a double-spend mined (perhaps from a miner who wasn't
on the network when the first transaction was broadcast).
That is a variation on the "Finney attack". We still don't
recommend anybody accept 0-confirmation transactions as final
payment for anything. This change keeps non-final transactions
from appearing in the wallet, and, assuming most of the network
accepts this change, will prevent them from being relayed until
they are final.
* Pass txid's to CCoinsView functions by reference instead of by value
* Add a method to swap CCoins, and use it in some places to avoid a
allocating copy + destruct.
* Optimize CCoinsViewCache::FetchCoins to do only a single search
through the backing map.
- don't show QR Code context menu, when USE_QRCODE=1 was not specified
when compiling the client
- re-work on_showQRCode_clicked() for better readability and remove an
unneeded duplicate check
- re-work on_signMessage_clicked() and on_verifyMessage_clicked() to match
foreach in on_showQRCode_clicked(), which seems more robust / cleaner
- re-order context menu stuff to match real context menu layout
- add comments for all private slots in the class
Several changes to make the native windows leveldb code compile
with mingw32 and run on 32-bit Windows:
* Remove -std=c++0x dependency (modified code to use NULL instead of
nullptr)
* Link with -lshlwapi
* Only #define snprintf/etc if compiling with Visual Studio
* Do not link against DbgHelp.lib (wrote a CreateDir instead of using
DbgHelp's MakeSureDirectoryPathExists
* Define WINVER=0x0500 so MinGW32 can use the 64-bit-filesystem Windows
api calls
* Define __USE_MINGW_ANSI_STDIO=1 to use MinGW's printf (which supports
%ll)
I also cleaned up makefile.mingw, assuming that dependencies would be in
the standard /usr/local/{include,lib} by default but allowing overriding
with make DEPSDIR=... etc
This actually simplifies some SPV code, as they can keep track of
a filtered block and its txn before accepting both in one step.
The previous argument was that SPV nodes should handle the txn the
same as any other free txn and then mark them as connected to a
block when they get the filtered block itself. However, it now
appears that SPV nodes will need to put in more effort to verify
loose txn than they would to verify txn in blocks, thus making it
more approriate to send the txn after the filtered block.
By specifying -txindex when initializing the database, a txid-to-diskpos
index is maintained in the blktree database. This database is used to
help answering getrawtransaction() RPC queries, when enabled.
Changing the -txindex value requires a -reindex; the client will abort
at startup if the database and the specified -txindex mismatch.
- this flag allows bitcoin-qt.exe / bitcoind.exe (32-bit application) to
handle addresses larger than 2GB (up to 3GB on x86 Windows and up to
4GB on x64 Windows)
Note that the default value for fRelayTxes is false, meaning we
now no longer relay tx inv messages before receiving the remote
peer's version message.
Fixes issue #2178 : attacker could penny-flood with invalid-signature
transactions to deduce which addresses belonged to your node.
I'm committing this early for code review; I still need to write up
a test plan.
Executive summary of fix: check all transactions received from the network
for penny-flood rate-limiting before adding to the memory pool. But do NOT
ratelimit transactions added to the memory pool:
- because of blockchain reorgs
- stored in the wallet and added at startup
- sent from the GUI or one of the send* RPC commands (CWallet::CommitTransaction)
The limit-free-transactions code really should be a method on CNode, with
counters per-peer. But that is a bigger change for another day.
- it was bad, that quite some messages were just talking about a database,
I think a user should know, if we are talking about wallet db or
block/coin db
- also adds a new init message for "Verifying block database integrity..."
- this pull adds an InitMessage() function to noui.cpp, which outputs init
messages to debug.log (this allows to remove some printf() calls from
init.cpp)
- change InitMessage() in bitcoin.cpp to also write init messages to
debug.log to ensure nothting is missing in the log because of the
removal of printf() calls in init.cpp
Client (SPV) mode never got implemented entirely, and whatever part was already
working, is likely not been tested (or even executed at all) for the past two
years. This removes it entirely.
If we want an SPV implementation, I think we should first get the block chain
data structures to be encapsulated in a class implementing a standard interface,
and then writing an alternate implementation with SPV semantics.
- add qSort() for cachedAddressTable, as qLowerBound() and qUpperBound()
require the list to be in ascending order (see
http://harmattan-dev.nokia.com/docs/library/html/qt4/qtalgorithms.html#qLowerBound)
- add a new check in AddressTableModel::setData() to just return, when no
changes were made to a label or an address (prevents entry duplication
issue)
- remove "rec->label = value.toString();" from
AddressTableModel::setData() as the label gets updated by
AddressTablePriv::updateEntry() anyway (seems @sipa added this line via
1025440184 (L6R225))
- add another new check in AddressTableModel::setData() to just return, if
a duplicate address was found (prevents address overwrite)
- add a new check to EditAddressDialog::setModel() to prevent setting an
invalid model
- re-work the switch-case statement in AddressTableModel::accept() to
always break (as return get's called anyway) and order the list to match
the enum definition
- make accept() in editaddressdialog.h a public slot, which it should be
- misc small coding style changes
Previously when a transaction was set to lock at a specific block the
calculation was reversed, returning a negative number. This broke the UI
and caused it to display %n in place of the actual number.
In addition the previous calculation would display "Open for 0 blocks"
when the block height was such that the next block created would
finalize the transaction. Inserted the word "more" and changed the
calculation so that the last message would be "Open for 1 more block" to
better match user expectations.
Since block validation happens in parallel, multiple threads may be
accessing the signature cache simultaneously. To prevent contention:
* Turn the signature cache lock into a shared mutex
* Make reading from the cache only acquire a shared lock
* Let block validations not store their results in the cache
* During block verification (when parallelism is requested), script
check actions are stored instead of being executed immediately.
* After every processed transactions, its signature actions are
pushed to a CScriptCheckQueue, which maintains a queue and some
synchronization mechanism.
* Two or more threads (if enabled) start processing elements from
this queue,
* When the block connection code is finished processing transactions,
it joins the worker pool until the queue is empty.
As cs_main is held the entire time, and all verification must be
finished before the block continues processing, this does not reach
the best possible performance. It is a less drastic change than
some more advanced mechanisms (like doing verification out-of-band
entirely, and rolling back blocks when a failure is detected).
The -par=N flag controls the number of threads (1-16). 0 means auto,
and is the default.
- ensure we use strCaption for printf and fprintf, as before it could
happen to have an error message in the debug.log, which had no "Error"
(or whatever) in front
- this prevents an interference with the IPC message queue (which is used
for URI processing) when running a testnet and mainnet instance in
parallel
- to check for testnet, I had to raise the ParseParameters() call in
main() to the topmost position
- a click on "Reset Options" sets all options to the default values by
removing all stored settings (QSettings), loading the defaults and
saving them as the new settings
- before the reset is executed the user is presented a confirmation dialog
- special casing was needed for StartAtStartup
- some users reported it as weird, that the estimated block count could be
lower than our own nodes block number (which is indeed true and not good)
- this pull adds a new default behaviour, which displays our own block
number as estimated block number, if own >= est. block count
- the pull raises space for nodes block counts in cPeerBlockCounts to 8 to
be more accurate
- also removes a reduntant setNumBlocks() call in RPCConsole and moves
initialisation of numBlocksAtStartup in ClientModel, where it belongs
-checklevel gets a new meaning:
0: verify blocks can be read from disk (like before)
1: verify (contextless) block validity (like before)
2: verify undo files can be read and have good checksums
3: verify coin database is consistent with the last few blocks
(close to level 6 before)
4: verify all validity rules of the last few blocks
Level 3 is the new default, as it's reasonably fast. As level 3 and
4 are implemented using an in-memory rollback of the database, they
are limited to as many blocks as possible without exceeding the
limits set by -dbcache. The default of -dbcache=25 allows for some
150-200 blocks to be rolled back.
In case an error is found, the application quits with a message
instructing the user to restart with -reindex. Better instructions,
and automatic recovery (when possible) or automatic reindexing are
left as future work.
Initialize the OutputDebugStringF mutex and file pointer using
boost::call_once, to be thread-safe.
Make the return value of OutputDebugStringF really be the number of
characters written (*printf() semantics).
Declare the fReopenDebugLog flag volatile, since it is changed from
a signal handler.
And don't declare OutputDebugStringF() as inline.
If the user was really after the fastest possible confirmation times
they would be manually setting a fee. In cases where the wallet builds
a transaction with a priority that is too low to qualify as free until
the next block, go ahead without a fee. Confirmation frequently takes
multiple blocks even when a minimum fee is provided.
This avoids a potential crash when trying to read the scrippubkeys on
transactions where the first input IsMine but some of the rest are not
when running listaddressgroupings.
When the coin database is out of date with the block database, the
best block in it is automatically switched to. This reconnection
process can take time, so allow it to be interrupted.
This also stops block connection as soon as shutdown is requested,
leading to a faster shutdown.
This problem is like earth (mostly harmless). After/during a
-reindex, it means the statistics about the last block file
reported in debug.log are always of blk00000.dat instead of the
last file. Apart from that, it means a few more database entries
need to be read when finding a file to append to the first time.
- even if we are allowed to fail pre-allocating, it's better to check
for sufficient space before calling AllocateFileRange() and if we
are out of disk space return with error()
- the above change allows us to remove the CheckDiskSpace() check
in CBlock::AcceptBlock()
- use it for displaying URI parsing warnings
- use it for displaying error and information in backup wallet function
(the information display is new and the error was a warning before)
- cleanup BitcoinGUI::incomingTransaction()
-- use message() + the information icon from message
-- comment out an unused parameter in the function definition and
declaration
-- move all pre-checks at the beginning of the function
In case a reorganisation fails, the internal state could become
inconsistent (memory only). Previously, a cache per block connect
or disconnect action was used, so blocks could not be applied in
a partial way. Extend this to a cache for the entire reorganisation,
making it atomic entirely. This also simplifies the code a bit.
- this allows to setup the trayicon before we have and want a trayicon menu
- should be of great use, when we remove that splash screen
- fixes a small bug with the toggleHideAction icon, which is not only used with
trayicon but also with the Mac dock
- fix ThreadSafeMessageBox always displays error icon
- allow to specify MSG_ERROR / MSG_WARNING or MSG_INFORMATION without a
custom caption / title
- allow to specify CClientUIInterface::ICON_ERROR / ICON_WARNING and
ICON_INFORMATION (which is default) as message box icon
- remove CClientUIInterface::OK from ThreadSafeMessageBox-calls, as
the OK button will be set as default, if none is specified
- prepend "Bitcoin - " to used captions
- rename BitcoinGUI::error() -> BitcoinGUI::message() and add function
documentation
- change all style parameters and enum flags to unsigned
- update code to use that new API
- update Client- and WalletModel to use new BitcoinGUI::message() and
rename the classes error() method into message()
- include the possibility to supply the wanted icon for messages from
Client- and WalletModel via "style" parameter
When a transaction A is in the memory pool, while a transaction B
(which shares an input with A) gets accepted into a block, A was
kept forever in the memory pool.
This commit adds a CTxMemPool::removeConflicts method, which
removes transactions that conflict with a given transaction, and
all their children.
This results in less transactions in the memory pool, and faster
construction of new blocks.
- can be triggerd by just adding -proxy=crashme with 0.7.1
- crash occured, when AppInit2() was left with return false; after the
first call to bitdb.open() (Step 6 in init)
- this is caused by GetDataDir() or .string() in CDBEnv::EnvShutdown()
called via the bitdb global destructor
- init fDbEnvInit and fMockDb to false in CDBEnv::CDBEnv()
These flags select features to be enabled/disabled during script
evaluation/checking, instead of several booleans passed along.
Currently these flags are defined:
* SCRIPT_VERIFY_P2SH: enable BIP16-style subscript evaluation
* SCRIPT_VERIFY_STRICTENC: enforce strict adherence to pubkey/sig encoding standards.
o Remove unused Leave and GetLock functions
o Make Enter and TryEnter private.
o Simplify Enter and TryEnter.
boost::unique_lock doesn't really know whether the
mutex it wraps is locked or not when the defer_lock
option is used.
The boost::recursive_mutex does not expose this
information, so unique_lock only infers this
knowledge. When taking the lock is defered, it
(randomly) assumes that the lock is not taken.
boost::unique_lock has the following definition:
unique_lock(Mutex& m_,defer_lock_t):
m(&m_),is_locked(false)
{}
bool owns_lock() const
{
return is_locked;
}
Thus it is a mistake to check owns_lock() in Enter
and TryEnter - they will always return false.
- remove an unwanted ";" at the end of the ~CCoinsView() destructor
- in FindBlockPos() and FindUndoPos() only call fclose(), is file is open
- fix an error string in the CBlockUndo class
feature in clang. These macros should primarily be used to
document which locks protect a given piece of data. Secondary it
can be used to document the set of held and excluded locks when
entering a function.
- remove pathEnv from CDBEnv, as this attribute is not needed
- change path parameter in ::Open() to a reference
- make nDbCache variable an unsigned integer
- remove a missplaced ";" behin ::IsMock()
- this allows the client to listen on via -bind specified addresses
(e.g. 127.0.0.1), even when a network (IPv4 in that case) was blocked
via e.g -onlynet="Tor"
- introduce enum BindFlags to avoid passing multiple bools to Bind()
- make -bind help text clear we ALWAYS listen on the specified address
- remove an unused variable
- remove 2 unneeded IsLimited() checks before calling Bind(), which does
these checks anyway
- usage case: specify -bind=127.0.0.1 -onlynet="Tor" to allow incoming
connections to a Tor hidden service, but still don't allow other IPv4
nodes to connect / get connected
As memset() can be optimized out by a compiler it should not be used in
privacy/security relevant code parts. OpenSSL provides the safe
OPENSSL_cleanse() function in crypto.h, which perfectly does the job of
clean and overwrite data.
For details see: http://www.viva64.com/en/b/0178/
- change memset() to OPENSSL_cleanse() where appropriate
- change a hard-coded number from netbase.cpp into a sizeof()
Flushes the blktree/ and coins/ databases, and reindexes the
block chain files, as if their contents was loaded via -loadblock.
Based on earlier work by Jeff Garzik.