wire: consistently use defer for returning scratch buffers

This commit is contained in:
Olaoluwa Osuntokun 2023-12-28 18:37:43 -08:00
parent 8c4da83890
commit b0e9636689
No known key found for this signature in database
GPG Key ID: 3BBD59E99B280306
19 changed files with 138 additions and 187 deletions

View File

@ -8,6 +8,7 @@ import (
"bytes"
"compress/bzip2"
"fmt"
"io"
"io/ioutil"
"net"
"os"
@ -66,7 +67,7 @@ func BenchmarkWriteVarInt1(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
WriteVarInt(ioutil.Discard, 0, 1)
WriteVarInt(io.Discard, 0, 1)
}
}
@ -76,7 +77,7 @@ func BenchmarkWriteVarInt3(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
WriteVarInt(ioutil.Discard, 0, 65535)
WriteVarInt(io.Discard, 0, 65535)
}
}
@ -86,7 +87,7 @@ func BenchmarkWriteVarInt5(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
WriteVarInt(ioutil.Discard, 0, 4294967295)
WriteVarInt(io.Discard, 0, 4294967295)
}
}
@ -96,7 +97,7 @@ func BenchmarkWriteVarInt9(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
WriteVarInt(ioutil.Discard, 0, 18446744073709551615)
WriteVarInt(io.Discard, 0, 18446744073709551615)
}
}
@ -159,7 +160,7 @@ func BenchmarkWriteVarIntBuf1(b *testing.B) {
buffer := binarySerializer.Borrow()
for i := 0; i < b.N; i++ {
WriteVarIntBuf(ioutil.Discard, 0, 1, buffer)
WriteVarIntBuf(io.Discard, 0, 1, buffer)
}
binarySerializer.Return(buffer)
}
@ -171,7 +172,7 @@ func BenchmarkWriteVarIntBuf3(b *testing.B) {
buffer := binarySerializer.Borrow()
for i := 0; i < b.N; i++ {
WriteVarIntBuf(ioutil.Discard, 0, 65535, buffer)
WriteVarIntBuf(io.Discard, 0, 65535, buffer)
}
binarySerializer.Return(buffer)
}
@ -183,7 +184,7 @@ func BenchmarkWriteVarIntBuf5(b *testing.B) {
buffer := binarySerializer.Borrow()
for i := 0; i < b.N; i++ {
WriteVarIntBuf(ioutil.Discard, 0, 4294967295, buffer)
WriteVarIntBuf(io.Discard, 0, 4294967295, buffer)
}
binarySerializer.Return(buffer)
}
@ -195,7 +196,7 @@ func BenchmarkWriteVarIntBuf9(b *testing.B) {
buffer := binarySerializer.Borrow()
for i := 0; i < b.N; i++ {
WriteVarIntBuf(ioutil.Discard, 0, 18446744073709551615, buffer)
WriteVarIntBuf(io.Discard, 0, 18446744073709551615, buffer)
}
binarySerializer.Return(buffer)
}
@ -292,7 +293,7 @@ func BenchmarkWriteVarStr4(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
WriteVarString(ioutil.Discard, 0, "test")
WriteVarString(io.Discard, 0, "test")
}
}
@ -302,7 +303,7 @@ func BenchmarkWriteVarStr10(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
WriteVarString(ioutil.Discard, 0, "test012345")
WriteVarString(io.Discard, 0, "test012345")
}
}
@ -343,7 +344,7 @@ func BenchmarkWriteVarStrBuf4(b *testing.B) {
buf := binarySerializer.Borrow()
for i := 0; i < b.N; i++ {
writeVarStringBuf(ioutil.Discard, 0, "test", buf)
writeVarStringBuf(io.Discard, 0, "test", buf)
}
binarySerializer.Return(buf)
}
@ -355,7 +356,7 @@ func BenchmarkWriteVarStrBuf10(b *testing.B) {
buf := binarySerializer.Borrow()
for i := 0; i < b.N; i++ {
writeVarStringBuf(ioutil.Discard, 0, "test012345", buf)
writeVarStringBuf(io.Discard, 0, "test012345", buf)
}
binarySerializer.Return(buf)
}
@ -392,7 +393,7 @@ func BenchmarkWriteOutPoint(b *testing.B) {
Index: 0,
}
for i := 0; i < b.N; i++ {
WriteOutPoint(ioutil.Discard, 0, 0, op)
WriteOutPoint(io.Discard, 0, 0, op)
}
}
@ -407,7 +408,7 @@ func BenchmarkWriteOutPointBuf(b *testing.B) {
Index: 0,
}
for i := 0; i < b.N; i++ {
writeOutPointBuf(ioutil.Discard, 0, 0, op, buf)
writeOutPointBuf(io.Discard, 0, 0, op, buf)
}
binarySerializer.Return(buf)
}
@ -480,7 +481,7 @@ func BenchmarkWriteTxOut(b *testing.B) {
txOut := blockOne.Transactions[0].TxOut[0]
for i := 0; i < b.N; i++ {
WriteTxOut(ioutil.Discard, 0, 0, txOut)
WriteTxOut(io.Discard, 0, 0, txOut)
}
}
@ -492,7 +493,7 @@ func BenchmarkWriteTxOutBuf(b *testing.B) {
buf := binarySerializer.Borrow()
txOut := blockOne.Transactions[0].TxOut[0]
for i := 0; i < b.N; i++ {
WriteTxOutBuf(ioutil.Discard, 0, 0, txOut, buf)
WriteTxOutBuf(io.Discard, 0, 0, txOut, buf)
}
binarySerializer.Return(buf)
}
@ -533,7 +534,7 @@ func BenchmarkWriteTxIn(b *testing.B) {
buf := binarySerializer.Borrow()
txIn := blockOne.Transactions[0].TxIn[0]
for i := 0; i < b.N; i++ {
writeTxInBuf(ioutil.Discard, 0, 0, txIn, buf)
writeTxInBuf(io.Discard, 0, 0, txIn, buf)
}
binarySerializer.Return(buf)
}
@ -608,15 +609,9 @@ func BenchmarkDeserializeTxLarge(b *testing.B) {
}
func BenchmarkDeserializeBlock(b *testing.B) {
f, err := os.Open(
buf, err := os.ReadFile(
"testdata/block-00000000000000000021868c2cefc52a480d173c849412fe81c4e5ab806f94ab.blk",
)
if err != nil {
b.Fatalf("Failed to open block file: %v", err)
}
defer f.Close()
buf, err := ioutil.ReadAll(f)
if err != nil {
b.Fatalf("Failed to read block data: %v", err)
}
@ -633,15 +628,9 @@ func BenchmarkDeserializeBlock(b *testing.B) {
}
func BenchmarkSerializeBlock(b *testing.B) {
f, err := os.Open(
buf, err := os.ReadFile(
"testdata/block-00000000000000000021868c2cefc52a480d173c849412fe81c4e5ab806f94ab.blk",
)
if err != nil {
b.Fatalf("Failed to open block file: %v", err)
}
defer f.Close()
buf, err := ioutil.ReadAll(f)
if err != nil {
b.Fatalf("Failed to read block data: %v", err)
}
@ -656,7 +645,7 @@ func BenchmarkSerializeBlock(b *testing.B) {
b.ResetTimer()
for i := 0; i < b.N; i++ {
block.Serialize(ioutil.Discard)
block.Serialize(io.Discard)
}
}
@ -667,7 +656,7 @@ func BenchmarkSerializeTx(b *testing.B) {
tx := blockOne.Transactions[0]
for i := 0; i < b.N; i++ {
tx.Serialize(ioutil.Discard)
tx.Serialize(io.Discard)
}
}
@ -710,7 +699,7 @@ func BenchmarkSerializeTxSmall(b *testing.B) {
b.ResetTimer()
for i := 0; i < b.N; i++ {
tx.Serialize(ioutil.Discard)
tx.Serialize(io.Discard)
}
}
@ -736,7 +725,7 @@ func BenchmarkSerializeTxLarge(b *testing.B) {
b.ResetTimer()
for i := 0; i < b.N; i++ {
tx.Serialize(ioutil.Discard)
tx.Serialize(io.Discard)
}
}
@ -805,7 +794,7 @@ func BenchmarkWriteBlockHeader(b *testing.B) {
header := blockOne.Header
for i := 0; i < b.N; i++ {
writeBlockHeader(ioutil.Discard, 0, &header)
writeBlockHeader(io.Discard, 0, &header)
}
}
@ -817,7 +806,7 @@ func BenchmarkWriteBlockHeaderBuf(b *testing.B) {
buf := binarySerializer.Borrow()
header := blockOne.Header
for i := 0; i < b.N; i++ {
writeBlockHeaderBuf(ioutil.Discard, 0, &header, buf)
writeBlockHeaderBuf(io.Discard, 0, &header, buf)
}
binarySerializer.Return(buf)
}

View File

@ -73,12 +73,13 @@ func (l binaryFreeList) Return(buf []byte) {
// free list and returns it as a uint8.
func (l binaryFreeList) Uint8(r io.Reader) (uint8, error) {
buf := l.Borrow()[:1]
defer l.Return(buf)
if _, err := io.ReadFull(r, buf); err != nil {
l.Return(buf)
return 0, err
}
rv := buf[0]
l.Return(buf)
return rv, nil
}
@ -87,12 +88,13 @@ func (l binaryFreeList) Uint8(r io.Reader) (uint8, error) {
// the resulting uint16.
func (l binaryFreeList) Uint16(r io.Reader, byteOrder binary.ByteOrder) (uint16, error) {
buf := l.Borrow()[:2]
defer l.Return(buf)
if _, err := io.ReadFull(r, buf); err != nil {
l.Return(buf)
return 0, err
}
rv := byteOrder.Uint16(buf)
l.Return(buf)
return rv, nil
}
@ -101,12 +103,13 @@ func (l binaryFreeList) Uint16(r io.Reader, byteOrder binary.ByteOrder) (uint16,
// the resulting uint32.
func (l binaryFreeList) Uint32(r io.Reader, byteOrder binary.ByteOrder) (uint32, error) {
buf := l.Borrow()[:4]
defer l.Return(buf)
if _, err := io.ReadFull(r, buf); err != nil {
l.Return(buf)
return 0, err
}
rv := byteOrder.Uint32(buf)
l.Return(buf)
return rv, nil
}
@ -115,12 +118,13 @@ func (l binaryFreeList) Uint32(r io.Reader, byteOrder binary.ByteOrder) (uint32,
// the resulting uint64.
func (l binaryFreeList) Uint64(r io.Reader, byteOrder binary.ByteOrder) (uint64, error) {
buf := l.Borrow()[:8]
defer l.Return(buf)
if _, err := io.ReadFull(r, buf); err != nil {
l.Return(buf)
return 0, err
}
rv := byteOrder.Uint64(buf)
l.Return(buf)
return rv, nil
}
@ -128,9 +132,11 @@ func (l binaryFreeList) Uint64(r io.Reader, byteOrder binary.ByteOrder) (uint64,
// writes the resulting byte to the given writer.
func (l binaryFreeList) PutUint8(w io.Writer, val uint8) error {
buf := l.Borrow()[:1]
defer l.Return(buf)
buf[0] = val
_, err := w.Write(buf)
l.Return(buf)
return err
}
@ -139,9 +145,11 @@ func (l binaryFreeList) PutUint8(w io.Writer, val uint8) error {
// writer.
func (l binaryFreeList) PutUint16(w io.Writer, byteOrder binary.ByteOrder, val uint16) error {
buf := l.Borrow()[:2]
defer l.Return(buf)
byteOrder.PutUint16(buf, val)
_, err := w.Write(buf)
l.Return(buf)
return err
}
@ -150,9 +158,11 @@ func (l binaryFreeList) PutUint16(w io.Writer, byteOrder binary.ByteOrder, val u
// writer.
func (l binaryFreeList) PutUint32(w io.Writer, byteOrder binary.ByteOrder, val uint32) error {
buf := l.Borrow()[:4]
defer l.Return(buf)
byteOrder.PutUint32(buf, val)
_, err := w.Write(buf)
l.Return(buf)
return err
}
@ -161,9 +171,11 @@ func (l binaryFreeList) PutUint32(w io.Writer, byteOrder binary.ByteOrder, val u
// writer.
func (l binaryFreeList) PutUint64(w io.Writer, byteOrder binary.ByteOrder, val uint64) error {
buf := l.Borrow()[:8]
defer l.Return(buf)
byteOrder.PutUint64(buf, val)
_, err := w.Write(buf)
l.Return(buf)
return err
}
@ -475,8 +487,9 @@ func writeElements(w io.Writer, elements ...interface{}) error {
// ReadVarInt reads a variable length integer from r and returns it as a uint64.
func ReadVarInt(r io.Reader, pver uint32) (uint64, error) {
buf := binarySerializer.Borrow()
defer binarySerializer.Return(buf)
n, err := ReadVarIntBuf(r, pver, buf)
binarySerializer.Return(buf)
return n, err
}
@ -545,8 +558,9 @@ func ReadVarIntBuf(r io.Reader, pver uint32, buf []byte) (uint64, error) {
// on its value.
func WriteVarInt(w io.Writer, pver uint32, val uint64) error {
buf := binarySerializer.Borrow()
defer binarySerializer.Return(buf)
err := WriteVarIntBuf(w, pver, val, buf)
binarySerializer.Return(buf)
return err
}
@ -616,8 +630,9 @@ func VarIntSerializeSize(val uint64) int {
// attacks and forced panics through malformed messages.
func ReadVarString(r io.Reader, pver uint32) (string, error) {
buf := binarySerializer.Borrow()
defer binarySerializer.Return(buf)
str, err := readVarStringBuf(r, pver, buf)
binarySerializer.Return(buf)
return str, err
}
@ -661,8 +676,9 @@ func readVarStringBuf(r io.Reader, pver uint32, buf []byte) (string, error) {
// itself.
func WriteVarString(w io.Writer, pver uint32, str string) error {
buf := binarySerializer.Borrow()
defer binarySerializer.Return(buf)
err := writeVarStringBuf(w, pver, str, buf)
binarySerializer.Return(buf)
return err
}
@ -696,8 +712,9 @@ func ReadVarBytes(r io.Reader, pver uint32, maxAllowed uint32,
fieldName string) ([]byte, error) {
buf := binarySerializer.Borrow()
defer binarySerializer.Return(buf)
b, err := ReadVarBytesBuf(r, pver, buf, maxAllowed, fieldName)
binarySerializer.Return(buf)
return b, err
}
@ -739,8 +756,9 @@ func ReadVarBytesBuf(r io.Reader, pver uint32, buf []byte, maxAllowed uint32,
// containing the number of bytes, followed by the bytes themselves.
func WriteVarBytes(w io.Writer, pver uint32, bytes []byte) error {
buf := binarySerializer.Borrow()
defer binarySerializer.Return(buf)
err := WriteVarBytesBuf(w, pver, bytes, buf)
binarySerializer.Return(buf)
return err
}

View File

@ -63,16 +63,15 @@ func (msg *MsgBlock) ClearTransactions() {
// opposed to decoding blocks from the wire.
func (msg *MsgBlock) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error {
buf := binarySerializer.Borrow()
defer binarySerializer.Return(buf)
err := readBlockHeaderBuf(r, pver, &msg.Header, buf)
if err != nil {
binarySerializer.Return(buf)
return err
}
txCount, err := ReadVarIntBuf(r, pver, buf)
if err != nil {
binarySerializer.Return(buf)
return err
}
@ -80,26 +79,23 @@ func (msg *MsgBlock) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) er
// It would be possible to cause memory exhaustion and panics without
// a sane upper bound on this count.
if txCount > maxTxPerBlock {
binarySerializer.Return(buf)
str := fmt.Sprintf("too many transactions to fit into a block "+
"[count %d, max %d]", txCount, maxTxPerBlock)
return messageError("MsgBlock.BtcDecode", str)
}
scriptBuf := scriptPool.Borrow()
defer scriptPool.Return(scriptBuf)
msg.Transactions = make([]*MsgTx, 0, txCount)
for i := uint64(0); i < txCount; i++ {
tx := MsgTx{}
err := tx.btcDecode(r, pver, enc, buf, scriptBuf[:])
if err != nil {
scriptPool.Return(scriptBuf)
binarySerializer.Return(buf)
return err
}
msg.Transactions = append(msg.Transactions, &tx)
}
scriptPool.Return(scriptBuf)
binarySerializer.Return(buf)
return nil
}
@ -140,19 +136,18 @@ func (msg *MsgBlock) DeserializeTxLoc(r *bytes.Buffer) ([]TxLoc, error) {
fullLen := r.Len()
buf := binarySerializer.Borrow()
defer binarySerializer.Return(buf)
// At the current time, there is no difference between the wire encoding
// at protocol version 0 and the stable long-term storage format. As
// a result, make use of existing wire protocol functions.
err := readBlockHeaderBuf(r, 0, &msg.Header, buf)
if err != nil {
binarySerializer.Return(buf)
return nil, err
}
txCount, err := ReadVarIntBuf(r, 0, buf)
if err != nil {
binarySerializer.Return(buf)
return nil, err
}
@ -160,13 +155,13 @@ func (msg *MsgBlock) DeserializeTxLoc(r *bytes.Buffer) ([]TxLoc, error) {
// It would be possible to cause memory exhaustion and panics without
// a sane upper bound on this count.
if txCount > maxTxPerBlock {
binarySerializer.Return(buf)
str := fmt.Sprintf("too many transactions to fit into a block "+
"[count %d, max %d]", txCount, maxTxPerBlock)
return nil, messageError("MsgBlock.DeserializeTxLoc", str)
}
scriptBuf := scriptPool.Borrow()
defer scriptPool.Return(scriptBuf)
// Deserialize each transaction while keeping track of its location
// within the byte stream.
@ -177,15 +172,11 @@ func (msg *MsgBlock) DeserializeTxLoc(r *bytes.Buffer) ([]TxLoc, error) {
tx := MsgTx{}
err := tx.btcDecode(r, 0, WitnessEncoding, buf, scriptBuf[:])
if err != nil {
scriptPool.Return(scriptBuf)
binarySerializer.Return(buf)
return nil, err
}
msg.Transactions = append(msg.Transactions, &tx)
txLocs[i].TxLen = (fullLen - r.Len()) - txLocs[i].TxStart
}
scriptPool.Return(scriptBuf)
binarySerializer.Return(buf)
return txLocs, nil
}
@ -196,29 +187,25 @@ func (msg *MsgBlock) DeserializeTxLoc(r *bytes.Buffer) ([]TxLoc, error) {
// database, as opposed to encoding blocks for the wire.
func (msg *MsgBlock) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error {
buf := binarySerializer.Borrow()
defer binarySerializer.Return(buf)
err := writeBlockHeaderBuf(w, pver, &msg.Header, buf)
if err != nil {
binarySerializer.Return(buf)
return err
}
err = WriteVarIntBuf(w, pver, uint64(len(msg.Transactions)), buf)
if err != nil {
binarySerializer.Return(buf)
return err
}
for _, tx := range msg.Transactions {
err = tx.btcEncode(w, pver, enc, buf)
if err != nil {
binarySerializer.Return(buf)
return err
}
}
binarySerializer.Return(buf)
return nil
}

View File

@ -53,27 +53,24 @@ func (msg *MsgCFCheckpt) AddCFHeader(header *chainhash.Hash) error {
// This is part of the Message interface implementation.
func (msg *MsgCFCheckpt) BtcDecode(r io.Reader, pver uint32, _ MessageEncoding) error {
buf := binarySerializer.Borrow()
defer binarySerializer.Return(buf)
// Read filter type
if _, err := io.ReadFull(r, buf[:1]); err != nil {
binarySerializer.Return(buf)
return err
}
msg.FilterType = FilterType(buf[0])
// Read stop hash
if _, err := io.ReadFull(r, msg.StopHash[:]); err != nil {
binarySerializer.Return(buf)
return err
}
// Read number of filter headers
count, err := ReadVarIntBuf(r, pver, buf)
if err != nil {
binarySerializer.Return(buf)
return err
}
binarySerializer.Return(buf)
// Refuse to decode an insane number of cfheaders.
if count > maxCFHeadersLen {
@ -99,17 +96,16 @@ func (msg *MsgCFCheckpt) BtcDecode(r io.Reader, pver uint32, _ MessageEncoding)
// This is part of the Message interface implementation.
func (msg *MsgCFCheckpt) BtcEncode(w io.Writer, pver uint32, _ MessageEncoding) error {
buf := binarySerializer.Borrow()
defer binarySerializer.Return(buf)
// Write filter type
buf[0] = byte(msg.FilterType)
if _, err := w.Write(buf[:1]); err != nil {
binarySerializer.Return(buf)
return err
}
// Write stop hash
if _, err := w.Write(msg.StopHash[:]); err != nil {
binarySerializer.Return(buf)
return err
}
@ -117,10 +113,8 @@ func (msg *MsgCFCheckpt) BtcEncode(w io.Writer, pver uint32, _ MessageEncoding)
count := len(msg.FilterHeaders)
err := WriteVarIntBuf(w, pver, uint64(count), buf)
if err != nil {
binarySerializer.Return(buf)
return err
}
binarySerializer.Return(buf)
for _, cfh := range msg.FilterHeaders {
_, err := w.Write(cfh[:])

View File

@ -49,33 +49,29 @@ func (msg *MsgCFHeaders) AddCFHash(hash *chainhash.Hash) error {
// This is part of the Message interface implementation.
func (msg *MsgCFHeaders) BtcDecode(r io.Reader, pver uint32, _ MessageEncoding) error {
buf := binarySerializer.Borrow()
defer binarySerializer.Return(buf)
// Read filter type
if _, err := io.ReadFull(r, buf[:1]); err != nil {
binarySerializer.Return(buf)
return err
}
msg.FilterType = FilterType(buf[0])
// Read stop hash
if _, err := io.ReadFull(r, msg.StopHash[:]); err != nil {
binarySerializer.Return(buf)
return err
}
// Read prev filter header
if _, err := io.ReadFull(r, msg.PrevFilterHeader[:]); err != nil {
binarySerializer.Return(buf)
return err
}
// Read number of filter headers
count, err := ReadVarIntBuf(r, pver, buf)
if err != nil {
binarySerializer.Return(buf)
return err
}
binarySerializer.Return(buf)
// Limit to max committed filter headers per message.
if count > MaxCFHeadersPerMsg {
@ -112,32 +108,28 @@ func (msg *MsgCFHeaders) BtcEncode(w io.Writer, pver uint32, _ MessageEncoding)
}
buf := binarySerializer.Borrow()
defer binarySerializer.Return(buf)
// Write filter type
buf[0] = byte(msg.FilterType)
if _, err := w.Write(buf[:1]); err != nil {
binarySerializer.Return(buf)
return err
}
// Write stop hash
if _, err := w.Write(msg.StopHash[:]); err != nil {
binarySerializer.Return(buf)
return err
}
// Write prev filter header
if _, err := w.Write(msg.PrevFilterHeader[:]); err != nil {
binarySerializer.Return(buf)
return err
}
err := WriteVarIntBuf(w, pver, uint64(count), buf)
if err != nil {
binarySerializer.Return(buf)
return err
}
binarySerializer.Return(buf)
for _, cfh := range msg.FilterHashes {
_, err := w.Write(cfh[:])

View File

@ -39,15 +39,15 @@ type MsgCFilter struct {
func (msg *MsgCFilter) BtcDecode(r io.Reader, pver uint32, _ MessageEncoding) error {
// Read filter type
buf := binarySerializer.Borrow()
defer binarySerializer.Return(buf)
if _, err := io.ReadFull(r, buf[:1]); err != nil {
binarySerializer.Return(buf)
return err
}
msg.FilterType = FilterType(buf[0])
// Read the hash of the filter's block
if _, err := io.ReadFull(r, msg.BlockHash[:]); err != nil {
binarySerializer.Return(buf)
return err
}
@ -55,7 +55,6 @@ func (msg *MsgCFilter) BtcDecode(r io.Reader, pver uint32, _ MessageEncoding) er
var err error
msg.Data, err = ReadVarBytesBuf(r, pver, buf, MaxCFilterDataSize,
"cfilter data")
binarySerializer.Return(buf)
return err
}
@ -70,19 +69,18 @@ func (msg *MsgCFilter) BtcEncode(w io.Writer, pver uint32, _ MessageEncoding) er
}
buf := binarySerializer.Borrow()
defer binarySerializer.Return(buf)
buf[0] = byte(msg.FilterType)
if _, err := w.Write(buf[:1]); err != nil {
binarySerializer.Return(buf)
return err
}
if _, err := w.Write(msg.BlockHash[:]); err != nil {
binarySerializer.Return(buf)
return err
}
err := WriteVarBytesBuf(w, pver, msg.Data, buf)
binarySerializer.Return(buf)
return err
}

View File

@ -52,8 +52,9 @@ func (msg *MsgGetBlocks) AddBlockLocatorHash(hash *chainhash.Hash) error {
// This is part of the Message interface implementation.
func (msg *MsgGetBlocks) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error {
buf := binarySerializer.Borrow()
defer binarySerializer.Return(buf)
if _, err := io.ReadFull(r, buf[:4]); err != nil {
binarySerializer.Return(buf)
return err
}
msg.ProtocolVersion = littleEndian.Uint32(buf[:4])
@ -61,10 +62,8 @@ func (msg *MsgGetBlocks) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding
// Read num block locator hashes and limit to max.
count, err := ReadVarIntBuf(r, pver, buf)
if err != nil {
binarySerializer.Return(buf)
return err
}
binarySerializer.Return(buf)
if count > MaxBlockLocatorsPerMsg {
str := fmt.Sprintf("too many block locator hashes for message "+
@ -100,18 +99,17 @@ func (msg *MsgGetBlocks) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding
}
buf := binarySerializer.Borrow()
defer binarySerializer.Return(buf)
littleEndian.PutUint32(buf[:4], msg.ProtocolVersion)
if _, err := w.Write(buf[:4]); err != nil {
binarySerializer.Return(buf)
return err
}
err := WriteVarIntBuf(w, pver, uint64(count), buf)
if err != nil {
binarySerializer.Return(buf)
return err
}
binarySerializer.Return(buf)
for _, hash := range msg.BlockLocatorHashes {
_, err := w.Write(hash[:])

View File

@ -22,12 +22,12 @@ type MsgGetCFCheckpt struct {
// This is part of the Message interface implementation.
func (msg *MsgGetCFCheckpt) BtcDecode(r io.Reader, pver uint32, _ MessageEncoding) error {
buf := binarySerializer.Borrow()
defer binarySerializer.Return(buf)
if _, err := io.ReadFull(r, buf[:1]); err != nil {
binarySerializer.Return(buf)
return err
}
msg.FilterType = FilterType(buf[0])
binarySerializer.Return(buf)
_, err := io.ReadFull(r, msg.StopHash[:])
return err
@ -37,12 +37,12 @@ func (msg *MsgGetCFCheckpt) BtcDecode(r io.Reader, pver uint32, _ MessageEncodin
// This is part of the Message interface implementation.
func (msg *MsgGetCFCheckpt) BtcEncode(w io.Writer, pver uint32, _ MessageEncoding) error {
buf := binarySerializer.Borrow()
defer binarySerializer.Return(buf)
buf[0] = byte(msg.FilterType)
if _, err := w.Write(buf[:1]); err != nil {
binarySerializer.Return(buf)
return err
}
binarySerializer.Return(buf)
_, err := w.Write(msg.StopHash[:])
return err

View File

@ -23,18 +23,17 @@ type MsgGetCFHeaders struct {
// This is part of the Message interface implementation.
func (msg *MsgGetCFHeaders) BtcDecode(r io.Reader, pver uint32, _ MessageEncoding) error {
buf := binarySerializer.Borrow()
defer binarySerializer.Return(buf)
if _, err := io.ReadFull(r, buf[:1]); err != nil {
binarySerializer.Return(buf)
return err
}
msg.FilterType = FilterType(buf[0])
if _, err := io.ReadFull(r, buf[:4]); err != nil {
binarySerializer.Return(buf)
return err
}
msg.StartHeight = littleEndian.Uint32(buf[:4])
binarySerializer.Return(buf)
_, err := io.ReadFull(r, msg.StopHash[:])
return err
@ -44,18 +43,17 @@ func (msg *MsgGetCFHeaders) BtcDecode(r io.Reader, pver uint32, _ MessageEncodin
// This is part of the Message interface implementation.
func (msg *MsgGetCFHeaders) BtcEncode(w io.Writer, pver uint32, _ MessageEncoding) error {
buf := binarySerializer.Borrow()
defer binarySerializer.Return(buf)
buf[0] = byte(msg.FilterType)
if _, err := w.Write(buf[:1]); err != nil {
binarySerializer.Return(buf)
return err
}
littleEndian.PutUint32(buf[:4], msg.StartHeight)
if _, err := w.Write(buf[:4]); err != nil {
binarySerializer.Return(buf)
return err
}
binarySerializer.Return(buf)
_, err := w.Write(msg.StopHash[:])
return err

View File

@ -27,18 +27,17 @@ type MsgGetCFilters struct {
// This is part of the Message interface implementation.
func (msg *MsgGetCFilters) BtcDecode(r io.Reader, pver uint32, _ MessageEncoding) error {
buf := binarySerializer.Borrow()
defer binarySerializer.Return(buf)
if _, err := io.ReadFull(r, buf[:1]); err != nil {
binarySerializer.Return(buf)
return err
}
msg.FilterType = FilterType(buf[0])
if _, err := io.ReadFull(r, buf[:4]); err != nil {
binarySerializer.Return(buf)
return err
}
msg.StartHeight = littleEndian.Uint32(buf[:4])
binarySerializer.Return(buf)
_, err := io.ReadFull(r, msg.StopHash[:])
return err
@ -48,18 +47,17 @@ func (msg *MsgGetCFilters) BtcDecode(r io.Reader, pver uint32, _ MessageEncoding
// This is part of the Message interface implementation.
func (msg *MsgGetCFilters) BtcEncode(w io.Writer, pver uint32, _ MessageEncoding) error {
buf := binarySerializer.Borrow()
defer binarySerializer.Return(buf)
buf[0] = byte(msg.FilterType)
if _, err := w.Write(buf[:1]); err != nil {
binarySerializer.Return(buf)
return err
}
littleEndian.PutUint32(buf[:4], msg.StartHeight)
if _, err := w.Write(buf[:4]); err != nil {
binarySerializer.Return(buf)
return err
}
binarySerializer.Return(buf)
_, err := w.Write(msg.StopHash[:])
return err

View File

@ -39,15 +39,15 @@ func (msg *MsgGetData) AddInvVect(iv *InvVect) error {
// This is part of the Message interface implementation.
func (msg *MsgGetData) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error {
buf := binarySerializer.Borrow()
defer binarySerializer.Return(buf)
count, err := ReadVarIntBuf(r, pver, buf)
if err != nil {
binarySerializer.Return(buf)
return err
}
// Limit to max inventory vectors per message.
if count > MaxInvPerMsg {
binarySerializer.Return(buf)
str := fmt.Sprintf("too many invvect in message [%v]", count)
return messageError("MsgGetData.BtcDecode", str)
}
@ -60,12 +60,10 @@ func (msg *MsgGetData) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding)
iv := &invList[i]
err := readInvVectBuf(r, pver, iv, buf)
if err != nil {
binarySerializer.Return(buf)
return err
}
msg.AddInvVect(iv)
}
binarySerializer.Return(buf)
return nil
}
@ -81,20 +79,19 @@ func (msg *MsgGetData) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding)
}
buf := binarySerializer.Borrow()
defer binarySerializer.Return(buf)
err := WriteVarIntBuf(w, pver, uint64(count), buf)
if err != nil {
binarySerializer.Return(buf)
return err
}
for _, iv := range msg.InvList {
err := writeInvVectBuf(w, pver, iv, buf)
if err != nil {
binarySerializer.Return(buf)
return err
}
}
binarySerializer.Return(buf)
return nil
}

View File

@ -49,15 +49,15 @@ func (msg *MsgGetHeaders) AddBlockLocatorHash(hash *chainhash.Hash) error {
// This is part of the Message interface implementation.
func (msg *MsgGetHeaders) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error {
buf := binarySerializer.Borrow()
defer binarySerializer.Return(buf)
if _, err := io.ReadFull(r, buf[:4]); err != nil {
binarySerializer.Return(buf)
return err
}
msg.ProtocolVersion = littleEndian.Uint32(buf[:4])
// Read num block locator hashes and limit to max.
count, err := ReadVarIntBuf(r, pver, buf)
binarySerializer.Return(buf)
if err != nil {
return err
}
@ -97,14 +97,14 @@ func (msg *MsgGetHeaders) BtcEncode(w io.Writer, pver uint32, enc MessageEncodin
}
buf := binarySerializer.Borrow()
defer binarySerializer.Return(buf)
littleEndian.PutUint32(buf[:4], msg.ProtocolVersion)
if _, err := w.Write(buf[:4]); err != nil {
binarySerializer.Return(buf)
return err
}
err := WriteVarIntBuf(w, pver, uint64(count), buf)
binarySerializer.Return(buf)
if err != nil {
return err
}

View File

@ -38,15 +38,15 @@ func (msg *MsgHeaders) AddBlockHeader(bh *BlockHeader) error {
// This is part of the Message interface implementation.
func (msg *MsgHeaders) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error {
buf := binarySerializer.Borrow()
defer binarySerializer.Return(buf)
count, err := ReadVarIntBuf(r, pver, buf)
if err != nil {
binarySerializer.Return(buf)
return err
}
// Limit to max block headers per message.
if count > MaxBlockHeadersPerMsg {
binarySerializer.Return(buf)
str := fmt.Sprintf("too many block headers for message "+
"[count %v, max %v]", count, MaxBlockHeadersPerMsg)
return messageError("MsgHeaders.BtcDecode", str)
@ -60,19 +60,16 @@ func (msg *MsgHeaders) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding)
bh := &headers[i]
err := readBlockHeaderBuf(r, pver, bh, buf)
if err != nil {
binarySerializer.Return(buf)
return err
}
txCount, err := ReadVarIntBuf(r, pver, buf)
if err != nil {
binarySerializer.Return(buf)
return err
}
// Ensure the transaction count is zero for headers.
if txCount > 0 {
binarySerializer.Return(buf)
str := fmt.Sprintf("block headers may not contain "+
"transactions [count %v]", txCount)
return messageError("MsgHeaders.BtcDecode", str)
@ -80,8 +77,6 @@ func (msg *MsgHeaders) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding)
msg.AddBlockHeader(bh)
}
binarySerializer.Return(buf)
return nil
}
@ -97,16 +92,16 @@ func (msg *MsgHeaders) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding)
}
buf := binarySerializer.Borrow()
defer binarySerializer.Return(buf)
err := WriteVarIntBuf(w, pver, uint64(count), buf)
if err != nil {
binarySerializer.Return(buf)
return err
}
for _, bh := range msg.Headers {
err := writeBlockHeaderBuf(w, pver, bh, buf)
if err != nil {
binarySerializer.Return(buf)
return err
}
@ -116,13 +111,10 @@ func (msg *MsgHeaders) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding)
// block headers, but it is required.
err = WriteVarIntBuf(w, pver, 0, buf)
if err != nil {
binarySerializer.Return(buf)
return err
}
}
binarySerializer.Return(buf)
return nil
}

View File

@ -47,15 +47,15 @@ func (msg *MsgInv) AddInvVect(iv *InvVect) error {
// This is part of the Message interface implementation.
func (msg *MsgInv) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error {
buf := binarySerializer.Borrow()
defer binarySerializer.Return(buf)
count, err := ReadVarIntBuf(r, pver, buf)
if err != nil {
binarySerializer.Return(buf)
return err
}
// Limit to max inventory vectors per message.
if count > MaxInvPerMsg {
binarySerializer.Return(buf)
str := fmt.Sprintf("too many invvect in message [%v]", count)
return messageError("MsgInv.BtcDecode", str)
}
@ -68,12 +68,10 @@ func (msg *MsgInv) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) erro
iv := &invList[i]
err := readInvVectBuf(r, pver, iv, buf)
if err != nil {
binarySerializer.Return(buf)
return err
}
msg.AddInvVect(iv)
}
binarySerializer.Return(buf)
return nil
}
@ -89,20 +87,19 @@ func (msg *MsgInv) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) erro
}
buf := binarySerializer.Borrow()
defer binarySerializer.Return(buf)
err := WriteVarIntBuf(w, pver, uint64(count), buf)
if err != nil {
binarySerializer.Return(buf)
return err
}
for _, iv := range msg.InvList {
err := writeInvVectBuf(w, pver, iv, buf)
if err != nil {
binarySerializer.Return(buf)
return err
}
}
binarySerializer.Return(buf)
return nil
}

View File

@ -50,14 +50,14 @@ func (msg *MsgMerkleBlock) BtcDecode(r io.Reader, pver uint32, enc MessageEncodi
}
buf := binarySerializer.Borrow()
defer binarySerializer.Return(buf)
err := readBlockHeaderBuf(r, pver, &msg.Header, buf)
if err != nil {
binarySerializer.Return(buf)
return err
}
if _, err := io.ReadFull(r, buf[:4]); err != nil {
binarySerializer.Return(buf)
return err
}
msg.Transactions = littleEndian.Uint32(buf[:4])
@ -65,11 +65,9 @@ func (msg *MsgMerkleBlock) BtcDecode(r io.Reader, pver uint32, enc MessageEncodi
// Read num block locator hashes and limit to max.
count, err := ReadVarIntBuf(r, pver, buf)
if err != nil {
binarySerializer.Return(buf)
return err
}
if count > maxTxPerBlock {
binarySerializer.Return(buf)
str := fmt.Sprintf("too many transaction hashes for message "+
"[count %v, max %v]", count, maxTxPerBlock)
return messageError("MsgMerkleBlock.BtcDecode", str)
@ -83,7 +81,6 @@ func (msg *MsgMerkleBlock) BtcDecode(r io.Reader, pver uint32, enc MessageEncodi
hash := &hashes[i]
_, err := io.ReadFull(r, hash[:])
if err != nil {
binarySerializer.Return(buf)
return err
}
msg.AddTxHash(hash)
@ -91,7 +88,6 @@ func (msg *MsgMerkleBlock) BtcDecode(r io.Reader, pver uint32, enc MessageEncodi
msg.Flags, err = ReadVarBytesBuf(r, pver, buf, maxFlagsPerMerkleBlock,
"merkle block flags size")
binarySerializer.Return(buf)
return err
}
@ -119,34 +115,30 @@ func (msg *MsgMerkleBlock) BtcEncode(w io.Writer, pver uint32, enc MessageEncodi
}
buf := binarySerializer.Borrow()
defer binarySerializer.Return(buf)
err := writeBlockHeaderBuf(w, pver, &msg.Header, buf)
if err != nil {
binarySerializer.Return(buf)
return err
}
littleEndian.PutUint32(buf[:4], msg.Transactions)
if _, err := w.Write(buf[:4]); err != nil {
binarySerializer.Return(buf)
return err
}
err = WriteVarIntBuf(w, pver, uint64(numHashes), buf)
if err != nil {
binarySerializer.Return(buf)
return err
}
for _, hash := range msg.Hashes {
_, err := w.Write(hash[:])
if err != nil {
binarySerializer.Return(buf)
return err
}
}
err = WriteVarBytesBuf(w, pver, msg.Flags, buf)
binarySerializer.Return(buf)
return err
}

View File

@ -36,15 +36,15 @@ func (msg *MsgNotFound) AddInvVect(iv *InvVect) error {
// This is part of the Message interface implementation.
func (msg *MsgNotFound) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error {
buf := binarySerializer.Borrow()
defer binarySerializer.Return(buf)
count, err := ReadVarIntBuf(r, pver, buf)
if err != nil {
binarySerializer.Return(buf)
return err
}
// Limit to max inventory vectors per message.
if count > MaxInvPerMsg {
binarySerializer.Return(buf)
str := fmt.Sprintf("too many invvect in message [%v]", count)
return messageError("MsgNotFound.BtcDecode", str)
}
@ -57,12 +57,10 @@ func (msg *MsgNotFound) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding)
iv := &invList[i]
err := readInvVectBuf(r, pver, iv, buf)
if err != nil {
binarySerializer.Return(buf)
return err
}
msg.AddInvVect(iv)
}
binarySerializer.Return(buf)
return nil
}
@ -78,20 +76,19 @@ func (msg *MsgNotFound) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding)
}
buf := binarySerializer.Borrow()
defer binarySerializer.Return(buf)
err := WriteVarIntBuf(w, pver, uint64(count), buf)
if err != nil {
binarySerializer.Return(buf)
return err
}
for _, iv := range msg.InvList {
err := writeInvVectBuf(w, pver, iv, buf)
if err != nil {
binarySerializer.Return(buf)
return err
}
}
binarySerializer.Return(buf)
return nil
}

View File

@ -82,16 +82,16 @@ func (msg *MsgReject) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) e
// Command that was rejected.
buf := binarySerializer.Borrow()
defer binarySerializer.Return(buf)
cmd, err := readVarStringBuf(r, pver, buf)
if err != nil {
binarySerializer.Return(buf)
return err
}
msg.Cmd = cmd
// Code indicating why the command was rejected.
if _, err := io.ReadFull(r, buf[:1]); err != nil {
binarySerializer.Return(buf)
return err
}
msg.Code = RejectCode(buf[0])
@ -100,11 +100,9 @@ func (msg *MsgReject) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) e
// reject code above) about why the command was rejected.
reason, err := readVarStringBuf(r, pver, buf)
if err != nil {
binarySerializer.Return(buf)
return err
}
msg.Reason = reason
binarySerializer.Return(buf)
// CmdBlock and CmdTx messages have an additional hash field that
// identifies the specific block or transaction.
@ -129,16 +127,16 @@ func (msg *MsgReject) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) e
// Command that was rejected.
buf := binarySerializer.Borrow()
defer binarySerializer.Return(buf)
err := writeVarStringBuf(w, pver, msg.Cmd, buf)
if err != nil {
binarySerializer.Return(buf)
return err
}
// Code indicating why the command was rejected.
buf[0] = byte(msg.Code)
if _, err := w.Write(buf[:1]); err != nil {
binarySerializer.Return(buf)
return err
}
@ -146,10 +144,8 @@ func (msg *MsgReject) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) e
// reject code above) about why the command was rejected.
err = writeVarStringBuf(w, pver, msg.Reason, buf)
if err != nil {
binarySerializer.Return(buf)
return err
}
binarySerializer.Return(buf)
// CmdBlock and CmdTx messages have an additional hash field that
// identifies the specific block or transaction.

View File

@ -456,10 +456,12 @@ func (msg *MsgTx) Copy() *MsgTx {
// database, as opposed to decoding transactions from the wire.
func (msg *MsgTx) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error {
buf := binarySerializer.Borrow()
defer binarySerializer.Return(buf)
sbuf := scriptPool.Borrow()
defer scriptPool.Return(sbuf)
err := msg.btcDecode(r, pver, enc, buf, sbuf[:])
scriptPool.Return(sbuf)
binarySerializer.Return(buf)
return err
}
@ -695,8 +697,9 @@ func (msg *MsgTx) DeserializeNoWitness(r io.Reader) error {
// database, as opposed to encoding transactions for the wire.
func (msg *MsgTx) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error {
buf := binarySerializer.Borrow()
defer binarySerializer.Return(buf)
err := msg.btcEncode(w, pver, enc, buf)
binarySerializer.Return(buf)
return err
}
@ -947,8 +950,9 @@ func readOutPointBuf(r io.Reader, pver uint32, version int32, op *OutPoint,
// w.
func WriteOutPoint(w io.Writer, pver uint32, version int32, op *OutPoint) error {
buf := binarySerializer.Borrow()
defer binarySerializer.Return(buf)
err := writeOutPointBuf(w, pver, version, op, buf)
binarySerializer.Return(buf)
return err
}
@ -986,8 +990,8 @@ func writeOutPointBuf(w io.Writer, pver uint32, version int32, op *OutPoint,
// and return when the method finishes.
//
// NOTE: b MUST either be nil or at least an 8-byte slice.
func readScriptBuf(r io.Reader, pver uint32, buf, s []byte, maxAllowed uint32,
fieldName string) ([]byte, error) {
func readScriptBuf(r io.Reader, pver uint32, buf, s []byte,
maxAllowed uint32, fieldName string) ([]byte, error) {
count, err := ReadVarIntBuf(r, pver, buf)
if err != nil {
@ -1070,8 +1074,9 @@ func ReadTxOut(r io.Reader, pver uint32, version int32, to *TxOut) error {
var s scriptSlab
buf := binarySerializer.Borrow()
defer binarySerializer.Return(buf)
err := readTxOutBuf(r, pver, version, to, buf, s[:])
binarySerializer.Return(buf)
return err
}
@ -1102,8 +1107,9 @@ func readTxOutBuf(r io.Reader, pver uint32, version int32, to *TxOut,
// new sighashes for witness transactions (BIP0143).
func WriteTxOut(w io.Writer, pver uint32, version int32, to *TxOut) error {
buf := binarySerializer.Borrow()
defer binarySerializer.Return(buf)
err := WriteTxOutBuf(w, pver, version, to, buf)
binarySerializer.Return(buf)
return err
}

View File

@ -89,8 +89,9 @@ func NewNetAddress(addr *net.TCPAddr, services ServiceFlag) *NetAddress {
// like version do not include the timestamp.
func readNetAddress(r io.Reader, pver uint32, na *NetAddress, ts bool) error {
buf := binarySerializer.Borrow()
defer binarySerializer.Return(buf)
err := readNetAddressBuf(r, pver, na, ts, buf)
binarySerializer.Return(buf)
return err
}
@ -152,8 +153,9 @@ func readNetAddressBuf(r io.Reader, pver uint32, na *NetAddress, ts bool,
// like version do not include the timestamp.
func writeNetAddress(w io.Writer, pver uint32, na *NetAddress, ts bool) error {
buf := binarySerializer.Borrow()
defer binarySerializer.Return(buf)
err := writeNetAddressBuf(w, pver, na, ts, buf)
binarySerializer.Return(buf)
return err
}