From 19008edd0faaa12938895b54aad83af820d703dc Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Tue, 19 Dec 2023 14:56:57 -0800 Subject: [PATCH] txscript: use a single shared scratch buffer in segwit sighash calc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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) ``` --- txscript/sighash.go | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/txscript/sighash.go b/txscript/sighash.go index 65a38a1e36..16c3c19c18 100644 --- a/txscript/sighash.go +++ b/txscript/sighash.go @@ -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 @@ -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. @@ -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 })