Skip to content

Commit 8c4da83

Browse files
cfromknechtRoasbeef
authored andcommitted
wire/msgblock+msgtx: user block-level script slab
1 parent d7396dc commit 8c4da83

File tree

2 files changed

+13
-19
lines changed

2 files changed

+13
-19
lines changed

wire/msgblock.go

+9-4
Original file line numberDiff line numberDiff line change
@@ -86,17 +86,19 @@ func (msg *MsgBlock) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) er
8686
return messageError("MsgBlock.BtcDecode", str)
8787
}
8888

89+
scriptBuf := scriptPool.Borrow()
8990
msg.Transactions = make([]*MsgTx, 0, txCount)
9091
for i := uint64(0); i < txCount; i++ {
9192
tx := MsgTx{}
92-
err := tx.btcDecode(r, pver, enc, buf)
93+
err := tx.btcDecode(r, pver, enc, buf, scriptBuf[:])
9394
if err != nil {
95+
scriptPool.Return(scriptBuf)
9496
binarySerializer.Return(buf)
9597
return err
9698
}
9799
msg.Transactions = append(msg.Transactions, &tx)
98100
}
99-
101+
scriptPool.Return(scriptBuf)
100102
binarySerializer.Return(buf)
101103

102104
return nil
@@ -164,22 +166,25 @@ func (msg *MsgBlock) DeserializeTxLoc(r *bytes.Buffer) ([]TxLoc, error) {
164166
return nil, messageError("MsgBlock.DeserializeTxLoc", str)
165167
}
166168

169+
scriptBuf := scriptPool.Borrow()
170+
167171
// Deserialize each transaction while keeping track of its location
168172
// within the byte stream.
169173
msg.Transactions = make([]*MsgTx, 0, txCount)
170174
txLocs := make([]TxLoc, txCount)
171175
for i := uint64(0); i < txCount; i++ {
172176
txLocs[i].TxStart = fullLen - r.Len()
173177
tx := MsgTx{}
174-
err := tx.btcDecode(r, 0, WitnessEncoding, buf)
178+
err := tx.btcDecode(r, 0, WitnessEncoding, buf, scriptBuf[:])
175179
if err != nil {
180+
scriptPool.Return(scriptBuf)
176181
binarySerializer.Return(buf)
177182
return nil, err
178183
}
179184
msg.Transactions = append(msg.Transactions, &tx)
180185
txLocs[i].TxLen = (fullLen - r.Len()) - txLocs[i].TxStart
181186
}
182-
187+
scriptPool.Return(scriptBuf)
183188
binarySerializer.Return(buf)
184189

185190
return txLocs, nil

wire/msgtx.go

+4-15
Original file line numberDiff line numberDiff line change
@@ -456,13 +456,15 @@ func (msg *MsgTx) Copy() *MsgTx {
456456
// database, as opposed to decoding transactions from the wire.
457457
func (msg *MsgTx) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error {
458458
buf := binarySerializer.Borrow()
459-
err := msg.btcDecode(r, pver, enc, buf)
459+
sbuf := scriptPool.Borrow()
460+
err := msg.btcDecode(r, pver, enc, buf, sbuf[:])
461+
scriptPool.Return(sbuf)
460462
binarySerializer.Return(buf)
461463
return err
462464
}
463465

464466
func (msg *MsgTx) btcDecode(r io.Reader, pver uint32, enc MessageEncoding,
465-
buf []byte) error {
467+
buf, sbuf []byte) error {
466468

467469
if _, err := io.ReadFull(r, buf[:4]); err != nil {
468470
return err
@@ -509,9 +511,6 @@ func (msg *MsgTx) btcDecode(r io.Reader, pver uint32, enc MessageEncoding,
509511
return messageError("MsgTx.BtcDecode", str)
510512
}
511513

512-
scriptBuf := scriptPool.Borrow()
513-
sbuf := scriptBuf[:]
514-
515514
// Deserialize the inputs.
516515
var totalScriptSize uint64
517516
txIns := make([]TxIn, count)
@@ -523,7 +522,6 @@ func (msg *MsgTx) btcDecode(r io.Reader, pver uint32, enc MessageEncoding,
523522
msg.TxIn[i] = ti
524523
err = readTxInBuf(r, pver, msg.Version, ti, buf, sbuf)
525524
if err != nil {
526-
scriptPool.Return(scriptBuf)
527525
return err
528526
}
529527
totalScriptSize += uint64(len(ti.SignatureScript))
@@ -532,15 +530,13 @@ func (msg *MsgTx) btcDecode(r io.Reader, pver uint32, enc MessageEncoding,
532530

533531
count, err = ReadVarIntBuf(r, pver, buf)
534532
if err != nil {
535-
scriptPool.Return(scriptBuf)
536533
return err
537534
}
538535

539536
// Prevent more output transactions than could possibly fit into a
540537
// message. It would be possible to cause memory exhaustion and panics
541538
// without a sane upper bound on this count.
542539
if count > uint64(maxTxOutPerMessage) {
543-
scriptPool.Return(scriptBuf)
544540
str := fmt.Sprintf("too many output transactions to fit into "+
545541
"max message size [count %d, max %d]", count,
546542
maxTxOutPerMessage)
@@ -557,7 +553,6 @@ func (msg *MsgTx) btcDecode(r io.Reader, pver uint32, enc MessageEncoding,
557553
msg.TxOut[i] = to
558554
err = readTxOutBuf(r, pver, msg.Version, to, buf, sbuf)
559555
if err != nil {
560-
scriptPool.Return(scriptBuf)
561556
return err
562557
}
563558
totalScriptSize += uint64(len(to.PkScript))
@@ -573,14 +568,12 @@ func (msg *MsgTx) btcDecode(r io.Reader, pver uint32, enc MessageEncoding,
573568
// varint which encodes the number of stack items.
574569
witCount, err := ReadVarIntBuf(r, pver, buf)
575570
if err != nil {
576-
scriptPool.Return(scriptBuf)
577571
return err
578572
}
579573

580574
// Prevent a possible memory exhaustion attack by
581575
// limiting the witCount value to a sane upper bound.
582576
if witCount > maxWitnessItemsPerInput {
583-
scriptPool.Return(scriptBuf)
584577
str := fmt.Sprintf("too many witness items to fit "+
585578
"into max message size [count %d, max %d]",
586579
witCount, maxWitnessItemsPerInput)
@@ -597,7 +590,6 @@ func (msg *MsgTx) btcDecode(r io.Reader, pver uint32, enc MessageEncoding,
597590
"script witness item",
598591
)
599592
if err != nil {
600-
scriptPool.Return(scriptBuf)
601593
return err
602594
}
603595
totalScriptSize += uint64(len(txin.Witness[j]))
@@ -607,7 +599,6 @@ func (msg *MsgTx) btcDecode(r io.Reader, pver uint32, enc MessageEncoding,
607599
}
608600

609601
if _, err := io.ReadFull(r, buf[:4]); err != nil {
610-
scriptPool.Return(scriptBuf)
611602
return err
612603
}
613604
msg.LockTime = littleEndian.Uint32(buf[:4])
@@ -670,8 +661,6 @@ func (msg *MsgTx) btcDecode(r io.Reader, pver uint32, enc MessageEncoding,
670661
offset += scriptSize
671662
}
672663

673-
scriptPool.Return(scriptBuf)
674-
675664
return nil
676665
}
677666

0 commit comments

Comments
 (0)