What changed, and why it matters
This commit fixes a memory-usage issue, not a security vulnerability. When reading PSBT data, the code was keeping a pointer to a large 4 MiB internal memory block even for tiny scripts. The patch copies the small script into its own compact memory slice so the large block can be released. It does not fix a bug that lets an attacker steal funds, crash the program, or bypass validation.
Treat as a routine memory-usage improvement. No security response is required. If backporting, do so for resource efficiency rather than vulnerability mitigation.
Security signals we found
memory retention reduction
no input validation change
no cryptographic change
no consensus rule change
test assertion added for capacity
Evidence from the diff
The change is in psbt/utils.go’s readTxOut helper. wire.ReadTxOut returns a wire.TxOut whose PkScript slice is backed by a shared 4 MiB slab used for script deserialization. PSBT inputs store the parsed WitnessUtxo, so small PkScripts retained a reference to the entire 4 MiB slab, causing unexpectedly high memory retention per input. The patch copies PkScript to a right-sized byte slice and updates the test to assert len(script) == cap(script). This is a memory-footprint optimization, not a correctness or security boundary fix.
Changed components
psbt/utils.gopsbt/strict_tx_values_test.goInspect captured patch +10 / −1
diff --git a/psbt/strict_tx_values_test.go b/psbt/strict_tx_values_test.go
index 83ed6bd..e31b8be 100644
--- a/psbt/strict_tx_values_test.go
+++ b/psbt/strict_tx_values_test.go
@@ -240,7 +240,9 @@ func TestParsesWitnessUtxoTxOutStrictly(t *testing.T) {
strictnessPSBTWithWitnessUtxo(t, txOutBytes),
), false)
require.NoError(t, err)
- require.Equal(t, pkScript, packet.Inputs[0].WitnessUtxo.PkScript)
+ script := packet.Inputs[0].WitnessUtxo.PkScript
+ require.Equal(t, pkScript, script)
+ require.Equal(t, len(script), cap(script))
malformedTxOut := append(append([]byte{}, txOutBytes...), 0x00)
_, err = NewFromRawBytes(bytes.NewReader(
diff --git a/psbt/utils.go b/psbt/utils.go
index baf7558..9bad772 100644
--- a/psbt/utils.go
+++ b/psbt/utils.go
@@ -315,6 +315,13 @@ func readTxOut(txout []byte) (*wire.TxOut, error) {
return nil, err
}
+ // wire.ReadTxOut stores PkScript in an internal 4 MiB script slab.
+ // Compact it before storing the TxOut in the PSBT so tiny witness
+ // scripts do not retain the full slab.
+ script := make([]byte, len(txOut.PkScript))
+ copy(script, txOut.PkScript)
+ txOut.PkScript = script
+
return txOut, nil
}
Why this scored 25/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.