Skip to content

Commit

Permalink
txscript: use a single shared scratch buffer in segwit sighash calc
Browse files Browse the repository at this point in the history
We used to use a lot of small buffers for serialization, but now we'll
use one buffer large enough, and slice into it when needed.

``
name                  old time/op    new time/op    delta
CalcWitnessSigHash-8    31.5µs ± 0%    29.2µs ± 0%   -7.05%  (p=0.000 n=10+10)

name                  old alloc/op   new alloc/op   delta
CalcWitnessSigHash-8    19.9kB ± 0%    18.5kB ± 0%   -7.14%  (p=0.000 n=10+10)

name                  old allocs/op  new allocs/op  delta
CalcWitnessSigHash-8       801 ± 0%       445 ± 0%  -44.44%  (p=0.000 n=10+10)
```
  • Loading branch information
Roasbeef committed Dec 19, 2023
1 parent 046a701 commit 19008ed
Showing 1 changed file with 12 additions and 15 deletions.
27 changes: 12 additions & 15 deletions txscript/sighash.go
Original file line number Diff line number Diff line change
Expand Up @@ -206,11 +206,12 @@ func calcWitnessSignatureHashRaw(subScript []byte, sigHashes *TxSigHashes,
}

sigHashBytes := chainhash.DoubleHashRaw(func(w io.Writer) error {
var scratch [8]byte

// First write out, then encode the transaction's version
// number.
var bVersion [4]byte
binary.LittleEndian.PutUint32(bVersion[:], uint32(tx.Version))
w.Write(bVersion[:])
binary.LittleEndian.PutUint32(scratch[:], uint32(tx.Version))
w.Write(scratch[:4])

// Next write out the possibly pre-calculated hashes for the
// sequence numbers of all inputs, and the hashes of the
Expand Down Expand Up @@ -269,12 +270,10 @@ func calcWitnessSignatureHashRaw(subScript []byte, sigHashes *TxSigHashes,

// Next, add the input amount, and sequence number of the input
// being signed.
var bAmount [8]byte
binary.LittleEndian.PutUint64(bAmount[:], uint64(amt))
w.Write(bAmount[:])
var bSequence [4]byte
binary.LittleEndian.PutUint32(bSequence[:], txIn.Sequence)
w.Write(bSequence[:])
binary.LittleEndian.PutUint64(scratch[:], uint64(amt))
w.Write(scratch[:])
binary.LittleEndian.PutUint32(scratch[:], txIn.Sequence)
w.Write(scratch[:4])

// If the current signature mode isn't single, or none, then we
// can re-use the pre-generated hashoutputs sighash fragment.
Expand All @@ -298,12 +297,10 @@ func calcWitnessSignatureHashRaw(subScript []byte, sigHashes *TxSigHashes,

// Finally, write out the transaction's locktime, and the sig
// hash type.
var bLockTime [4]byte
binary.LittleEndian.PutUint32(bLockTime[:], tx.LockTime)
w.Write(bLockTime[:])
var bHashType [4]byte
binary.LittleEndian.PutUint32(bHashType[:], uint32(hashType))
w.Write(bHashType[:])
binary.LittleEndian.PutUint32(scratch[:], tx.LockTime)
w.Write(scratch[:4])
binary.LittleEndian.PutUint32(scratch[:], uint32(hashType))
w.Write(scratch[:4])

return nil
})
Expand Down

0 comments on commit 19008ed

Please sign in to comment.