Optimize duplicate transaction input check.

Profiling showed the duplicate transaction input check was taking around
6% of the total CheckTransactionSanity processing time.  This was largely
due to using fmt.Sprintf to generate the map key.

This commit modifies the check instead to use the actual output as a map
key.

The following benchmark results show the difference:

Before: BenchmarkOldDuplicatInputCheck    100000     21787 ns/op
After:  BenchmarkNewDuplicatInputCheck   2000000       937 ns/op

Closes #2
This commit is contained in:
Dave Collins 2013-10-26 14:31:15 -05:00
parent 89d86d07ac
commit b6e4ae4441

View file

@ -230,14 +230,12 @@ func CheckTransactionSanity(tx *btcwire.MsgTx) error {
} }
// Check for duplicate transaction inputs. // Check for duplicate transaction inputs.
existingTxOut := make(map[string]bool) existingTxOut := make(map[btcwire.OutPoint]bool)
for _, txIn := range tx.TxIn { for _, txIn := range tx.TxIn {
prevOut := &txIn.PreviousOutpoint if _, exists := existingTxOut[txIn.PreviousOutpoint]; exists {
key := fmt.Sprintf("%v%v", prevOut.Hash, prevOut.Index)
if _, exists := existingTxOut[key]; exists {
return RuleError("transaction contains duplicate outpoint") return RuleError("transaction contains duplicate outpoint")
} }
existingTxOut[key] = true existingTxOut[txIn.PreviousOutpoint] = true
} }
// Coinbase script length must be between min and max length. // Coinbase script length must be between min and max length.