Compare the block download timeout to what the timeout would be if calculated
based on current time and current value of nQueuedValidatedHeaders, but
ignoring other in-flight blocks from the same peer. If the calculation based on
present conditions is shorter, then set that to be the time after which we
disconnect the peer for not delivering this block.
Some tests in CheckBlockIndex require chainActive.Tip(), but when reindexing, chainActive has not been set on the first call to CheckBlockIndex.
reindex.py starts a node, mines 3 blocks, stops, and reindexes with CheckBlockIndex enabled.
SendMessages will now call getheaders on both inbound and outbound peers,
once the headers chain is close to synced. It will also try downloading
blocks from inbound peers once we're out of initial block download (so
inbound peers will participate in parallel block fetching for the last day
or two of blocks being downloaded).
This adds more tests to CheckBlockIndex:
- HAVE_DATA is true iff nTx > 0
- BLOCK_VALID_TRANSACTIONS is true iff nTx > 0
- BLOCK_VALID_TRANSACTIONS is true for a block and all parents iff
nChainTx > 0
This adds a -checkblockindex (defaulting to true for regtest), which occasionally
does a full consistency check for mapBlockIndex, setBlockIndexCandidates, chainActive, and
mapBlocksUnlinked.
Adds a regression test for the wallet's ResendWalletTransactions function, which uses a new, hidden RPC command "resendwallettransactions."
I refactored main's Broadcast signal so it is passed the best-block time, which let me remove a global variable shared between main.cpp and the wallet (nTimeBestReceived).
I also manually tested the "rebroadcast unconfirmed every half hour or so" functionality by:
1. Running bitcoind -connect=0.0.0.0:8333
2. Creating a couple of send-to-self transactions
3. Connect to a peer using -addnode
4. Waited a while, monitoring debug.log, until I see:
```2015-03-23 18:48:10 ResendWalletTransactions: rebroadcast 2 unconfirmed transactions```
One last change: don't bother putting ResendWalletTransactions messages in debug.log unless unconfirmed transactions were actually rebroadcast.
When re-indexing, there are a few cases where garbage data may be skipped in
the block files. In these cases, the indices are correctly written to the index
db, however the pointer to the next position for writing in the current block
file is calculated by adding the sizes of the valid blocks found.
As a result, when the re-index is finished, the index db is correct for all
existing blocks, but the next block will be written to an incorrect offset,
likely overwriting existing blocks.
Rather than using the sum of all valid blocks to determine the next write
position, use the end of the last block written to the file. Don't assume that
the current block is the last one in the file, since they may be read
out-of-order.
Normally bitcoin core does not display any network originated strings without
sanitizing or hex encoding. This wasn't done for strcommand in many places.
This could be used to play havoc with a terminal displaying the logs,
especially with printtoconsole in use.
Thanks to Evil-Knievel for reporting this issue.
The only time when a client sends a "getaddr" message is when he
esatblishes an Outbound connection (see ProcessMessage() in
src/main.cpp). Another bitcoin client is expected to receive a
"getaddr" message only on Inbound connection. Ignoring "gettaddr"
requests on Outbound connections can resolve potential privacy issues
(and as was said such request normally do not happen anyway).
Instead, create a separate function that applies the undo operation of a
CTxInUndo object onto a CCoinsViewCache. This method is used from
DisconnectBlock.
Note that this will also require translation changes in Transifex for the key
"A fee higher than %1 is considered an insanely high fee." which is now
"A fee higher than %1 is considered an absurdly high fee."
Signed-off-by: Daira Hopwood <daira@jacaranda.org>
This harmonizes the block fetch timeout with the existing ping timeout
and eliminates a guaranteed eventual failure from congestion collapse
for a network operating right at its limit.
It's unlikely that we wouldn't suffer other failures if we were really
anywhere near the network's limit, and a complete avoidance of congestion
collapse risk requires (I think) an exponential back-off. So this isn't
a major concern, but I think it's also useful for reducing the complexity
of understanding out timeouts.
This will disconnect peers that do not transfer a block in 10 minutes, plus
5 minutes for every previously queued block with validated headers
(accomodating downstream bandwidth down to a few kilobytes per second - below
that the node would have trouble staying synchronized anyway).
856e862 namespace: drop most boost namespaces and a few header cleanups (Cory Fields)
9b1ab86 namespace: drop boost::assign altogether here (Cory Fields)
a324199 namespace: remove boost namespace pollution (Cory Fields)
If uint256() constructor takes a string, uint256(0) will become
dangerous when uint256 does not take integers anymore (it will go
through std::string(const char*) making a NULL string, and the explicit
keyword is no help).
Previous behavior with IsFinalTx() being an IsStandard() rule was rather
confusing and interferred with testing of protocols that depended on
nLockTime.
With the splashscreen being able to be closed it is possible to
shutdown during the lengthy verifyDB method. (Takes about a minute
on my machine). This change allows us to shutdown much sooner.
Github-Pull: #5557
1b178a7 Bugfix: ConnectBlock: In case the genesis block gets in with fJustCheck, behave correctly (Luke Dashjr)
228d238 Make CCoinsViewCache's copy constructor private (Luke Dashjr)
Don't allow immediate inv driven block downloads if
a peer already has MAX_BLOCKS_IN_TRANSIT_PER_PEER
active downloads. Prevents bogus inv spam from
blowing up block transfer tracking data structures.
This still leaves transactions in mempool that are potentially
invalid if the maturity period has been reorged out of, but at
least they're not missing inputs entirely.
9ec75c5 Add a locking mechanism to IsInitialBlockDownload to ensure it never goes from false to true. (Ruben Dario Ponticelli)
a2d0fc6 Fix IsInitialBlockDownload which was broken by headers first. (Ruben Dario Ponticelli)
There are 3 pieces of data that are maintained on disk. The actual block
and undo data, the block index (which can refer to positions on disk),
and the chainstate (which refers to the best block hash).
Earlier, there was no guarantee that blocks were written to disk before
block index entries referring to them were written. This commit introduces
dirty flags for block index data, and delays writing entries until the actual
block data is flushed.
With this stricter ordering in writes, it is now safe to not always flush
after every block, so there is no need for the IsInitialBlockDownload()
check there - instead we just write whenever enough time has passed or
the cache size grows too large. Also updating the wallet's best known block
is delayed until this is done, otherwise the wallet may end up referring to an
unknown block.
In addition, only do a write inside the block processing loop if necessary
(because of cache size exceeded). Otherwise, move the writing to a point
after processing is done, after relaying.
Like in a real world situation, a safe mode test should also be visible in the
UI. A test of safe mode is furthermore mostly relevant for developers, so it
should not be overwritten by a warning about a pre-release test build.
Previously, AcceptBlockHeader did not check the header (in particular
PoW). This made the client accept invalid-PoW-headers from peers in
headers-first sync.
Previously transactions were only tested again the
STANDARD_SCRIPT_VERIFY_FLAGS prior to mempool acceptance, so any bugs in
those flags that allowed actually-invalid transactions to pass would
result in allowing invalid transactions into the mempool. Fortunately
there is a second check in CreateNewBlock() that would prevent those
transactions from being mined, resulting in an invalid block, however
this could still be exploited as a DoS attack.
This is a simplified re-do of closed pull #3088.
This patch eliminates the privacy and reliability problematic use
of centralized web services for discovering the node's addresses
for advertisement.
The Bitcoin protocol already allows your peers to tell you what
IP they think you have, but this data isn't trustworthy since
they could lie. So the challenge is using it without creating a
DOS vector.
To accomplish this we adopt an approach similar to the one used
by P2Pool: If we're announcing and don't have a better address
discovered (e.g. via UPNP) or configured we just announce to
each peer the address that peer told us. Since peers could
already replace, forge, or drop our address messages this cannot
create a new vulnerability... but if even one of our peers is
giving us a good address we'll eventually make a useful
advertisement.
We also may randomly use the peer-provided address for the
daily rebroadcast even if we otherwise have a seemingly routable
address, just in case we've been misconfigured (e.g. by UPNP).
To avoid privacy problems, we only do these things if discovery
is enabled.
50b43fd Be a bit more verbose during -loadblock if we already have blocks (Matt Corallo)
8375e22 Fix -loadblock after shutdown during IBD (Matt Corallo)
4ead850 Fix for crash during block download (Matt Corallo)
1bea2bb Rename ProcessBlock to ProcessNewBlock to indicate change of behaviour, and document it (Luke Dashjr)
d29a291 Rename RPC_TRANSACTION_* errors to RPC_VERIFY_* and use RPC_VERIFY_ERROR for submitblock (Luke Dashjr)
f877aaa Bugfix: submitblock: Use a temporary CValidationState to determine accurately the outcome of ProcessBlock, now that it no longer does the full block validity check (Luke Dashjr)
24e8896 Add CValidationInterface::BlockChecked notification (Luke Dashjr)
a873823 CAutoFile: Explicit Get() and remove unused methods (Wladimir J. van der Laan)
fef24ca Add IsNull() to class CAutoFile and remove operator ! (Ruben Dario Ponticeli)
Previous refactorings broke the ability to rebuild the chainstate by deleting the chainstate
directory, resulting in an incorrect "Incorrect or no genesis block found" error message. Fix
that.
Also, improve the performance of ActivateBestBlockStep by using the skiplist to only discover
a few potential blocks to connect at a time, instead of all blocks forever - as we likely bail
out after connecting a single one anyway.
Instead of skipping to the last reindexed block in each file (which could
jump over processed out-of-order blocks), just skip each already processed
block individually.
Remember out-of-order block headers along with disk positions. This is
likely the simplest and least-impact way to make -reindex work with
headers first.
Based on top of #4468.
Many changes:
* Do not use 'getblocks', but 'getheaders', and use it to build a headers tree.
* Blocks are fetched in parallel from all available outbound peers, using a
limited moving window. When one peer stalls the movement of the window, it is
disconnected.
* No more orphan blocks. At all. We only ever request a block for which we have
verified the headers, and store it to disk immediately. This means that a
disk-fill attack would require PoW.
* Require protocol version 31800 for every peer (released in december 2010).
* No more syncnode (we sync from everyone we can, though limited to 1 during
initial *headers* sync).
* Introduce some extra named constants, comments and asserts.
This adds a -regetest-only undocumented (for regression testing only)
command-line option -blockversion=N to set block.nVersion.
Adds to the "has the rest of the network upgraded to a
block.nVersion we don't understand" code so it calls
-alertnotify when 51 of the last 100 blocks are up-version.
But it only alerts once, not with every subsequent new, upversion
block.
And adds a forknotify.py regression test to make sure it works.
Tested using forknotify.py:
Before adding CAlert::Notify, get:
Assertion failed: -alertnotify did not warn of up-version blocks
Before adding code to only alert once:
Assertion failed: -alertnotify excessive warning of up-version blocks
After final code in this pull:
Tests successful
7c70438 Get rid of the dummy CCoinsViewCache constructor arg (Pieter Wuille)
ed27e53 Add coins_tests with a large randomized CCoinViewCache test. (Pieter Wuille)
058b08c Do not keep fully spent but unwritten CCoins entries cached. (Pieter Wuille)
c9d1a81 Get rid of CCoinsView's SetCoins and SetBestBlock. (Pieter Wuille)
f28aec0 Use ModifyCoins instead of mutable GetCoins. (Pieter Wuille)
e790c37 Replace SCRIPT_VERIFY_NOCACHE by flag directly to checker (Pieter Wuille)
5c1e798 Make signature cache optional (Pieter Wuille)
c7829ea Abstract out SignatureChecker (Pieter Wuille)
938bcce CAutoFile: make file private (Philip Kaufmann)
0c35486 CBufferedFile: add explicit close function (Philip Kaufmann)
c9fb27d CBufferedFile: convert into a non-refcounted RAII wrapper (Philip Kaufmann)
There is only one message passed to AbortNode() that makes sense to
translate to the user specifically: Disk space is low. For the others
show a generic message and refer to debug.log for details.
Reduces the number of confusing jargon translation messages.
- it now takes over the passed file descriptor and closes it in the
destructor
- this fixes a leak in LoadExternalBlockFile(), where an exception could
cause the file to not getting closed
- disallow copies (like recently added for CAutoFile)
- make nType and nVersion private
4705902 Avoid introducing a virtual into CChainParams (Wladimir J. van der Laan)
5e2e7fc Suggested corrections on comments, variable names. Also new test case testing the PoW skip in UNITTEST. (SergioDemianLerner)
a25fd6b Switch testing framework from MAIN to new UNITTEST network (SergioDemianLerner)
f74fc9b Print input index when signature validation fails, to aid debugging. (Mark Friedenbach)
217a5c9 When transaction outputs exceed inputs, show the offending amounts so as to aid debugging. (Mark Friedenbach)
Move the txid duplicates check into BuildMerkleTree, where it can be done
much more efficiently (without needing to build a full txid set to detect
duplicates).
The previous version (using the std::set<uint256> to detect duplicates) was
also slightly too weak. A block mined with actual duplicate transactions
(which is invalid, due to the inputs of the duplicated transactions being
seen as double spends) would trigger the duplicates logic, resulting in the
block not being stored on disk, and rerequested. This change fixes that by
only triggering in the case of duplicated transactions that can actually
result in an identical merkle root.
Instead of storing CCoins entries directly in CCoinsMap, store a CCoinsCacheEntry
which additionally keeps track of whether a particular entry is:
* dirty: potentially different from its parent view.
* fresh: the parent view is known to not have a non-pruned version.
This allows us to skip non-dirty cache entries when pushing batches of changes up,
and to remove CCoins entries about transactions that are fully spent before the
parent cache learns about them.
All direct modifications are now done through ModifyCoins, and BatchWrite is
used for pushing batches of queued modifications up, so we don't need the
low-level SetCoins and SetBestBlock anymore in the top-level CCoinsView class.
Replace the mutable non-copying GetCoins method with a ModifyCoins, which
returns an encapsulated iterator, so we can keep track of concurrent
modifications (as iterators can be invalidated by those) and run cleanup
code after a modification is finished.
This also removes the overloading of the 'GetCoins' name.
There is no reason to store thousands of orphan transactions;
normally an orphan's parents will either be broadcast or
mined reasonably quickly.
This pull drops the maximum number of orphans from 10,000 down
to 100, and adds a command-line option (-maxorphantx) that is
just like -maxorphanblocks to override the default.
Prevent denial-of-service attacks by banning
peers that send us invalid orphan transactions
and only storing orphan transactions given to
us by a peer while the peer is connected.