From 318c4760c02d494542d0b7ea9b636351a99fe458 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 19 Oct 2016 14:30:40 -0500 Subject: [PATCH] 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 --- blockchain/validate.go | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/blockchain/validate.go b/blockchain/validate.go index 1745f4ea..3499fde4 100644 --- a/blockchain/validate.go +++ b/blockchain/validate.go @@ -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