Remove orphan transactions from memory once
all of their parent transactions are received
and they're still not valid.
Thanks to Sergio Demian Lerner for suggesting this fix.
Loop over all inputs doing inexpensive validity checks first,
and then loop over them a second time doing expensive signature
checks. This helps prevent possible CPU exhaustion attacks
where an attacker tries to make a victim waste time checking
signatures for invalid transactions.
(Partial/merge of upstream 9247134eaba9a1d0fa74f22de238af1476663005, 1a3f0da9229a8e524d1010cdc8bd3b9da71fe529, and 3e343522226e6c249f5cb05436eec347b87c6361)
Immediately issue a "getblocks", instead of a "getdata" (which will
trigger the relevant "inv" to be sent anyway), and only do so when
the previous set of invs led us into a known and attached part of
the block tree.
Pull request #948 introduced a fix for nodes stuck on a long side branch
of the main chain. The fix was non-functional however, as the additional
getdata request was created in a first step of processing, but dropped
in a second step as it was considered redundant. This commits fixes it
by sending the request directly.
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.
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.
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.
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.