blockchain: Only enforce BIP0030 prior to BIP0034.

This modifies the code to only enforce the fairly expensive BIP0030
(duplicate transcactions) checks when the chain has not yet reached the
BIP0034 activation height (and is not one of the 2 special historical
blocks that break the rule and prompted BIP0034 to being with) since
that BIP made it impossible to create duplicate coinbases and thus
removed the possibility of creating transactions that overwrite older
ones.

This is a rather large optimization because the check is expensive due
to involving a ton of cache misses in the utxoset.  For example, the
following are times it took to perform the BIP0030 check on blocks
425490 - 425502 and a system with a relatively old Hitachi spinner HDD:

block 425490: 674.5857ms
block 425491: 726.5923ms
block 425492: 827.6051ms
block 425493: 680.0863ms
block 425494: 722.0917ms
block 425495: 700.0889ms
block 425496: 647.5823ms
block 425497: 445.0565ms
block 425498: 602.5765ms
block 425499: 375.0476ms
block 425500: 771.0979ms
block 425501: 461.5586ms
block 425502: 603.0766ms

As can be seen from these numbers, this reduces the block validation
time by an average of just over half a second for the given
representative data set and hardware.

Signed-off-by: Dave Collins <davec@conformal.com>
This commit is contained in:
Dave Collins 2016-10-19 14:30:40 -05:00
parent 2e93ea6ca6
commit 318c4760c0
No known key found for this signature in database
GPG key ID: B8904D9D9C93D1F2

View file

@ -979,11 +979,18 @@ func (b *BlockChain) checkConnectBlock(node *blockNode, block *btcutil.Block, vi
// spent. See the documentation for checkBIP0030 for more details.
//
// There are two blocks in the chain which violate this rule, so the
// check must be skipped for those blocks. The isBIP0030Node function is
// used to determine if this block is one of the two blocks that must be
// skipped.
enforceBIP0030 := !isBIP0030Node(node)
if enforceBIP0030 {
// check must be skipped for those blocks. The isBIP0030Node function
// is used to determine if this block is one of the two blocks that must
// be skipped.
//
// In addition, as of BIP0034, duplicate coinbases are no longer
// possible due to its requirement for including the block height in the
// coinbase and thus it is no longer possible to create transactions
// that 'overwrite' older ones. Therefore, only enforce the rule if
// BIP0034 is not yet active. This is a useful optimization because the
// BIP0030 check is expensive since it involves a ton of cache misses in
// the utxoset.
if !isBIP0030Node(node) && (node.height < b.chainParams.BIP0034Height) {
err := b.checkBIP0030(node, block, view)
if err != nil {
return err