From b3e031c1f90d68eb69c8a25d592d2a6498abe7d5 Mon Sep 17 00:00:00 2001 From: Josh Rickmar Date: Mon, 23 Jun 2014 22:01:21 -0500 Subject: [PATCH] Add NewBlockFromReader and NewTxFromReader. While here, remove the serializedTx field from Tx. This field was originally intended to be used to cache the bytes of the serialized transaction, but it was never used and can effectively leak memory if the Tx was created with a call to NewTxFromBytes. ok @davecgh --- block.go | 21 ++++++++++++++++----- tx.go | 23 ++++++++++++++--------- 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/block.go b/block.go index 0e5e514..d23a326 100644 --- a/block.go +++ b/block.go @@ -8,6 +8,7 @@ import ( "bytes" "fmt" "github.com/conformal/btcwire" + "io" ) // OutOfRangeError describes an error due to accessing an element that is out @@ -206,18 +207,28 @@ func NewBlock(msgBlock *btcwire.MsgBlock) *Block { // NewBlockFromBytes returns a new instance of a bitcoin block given the // serialized bytes. See Block. func NewBlockFromBytes(serializedBlock []byte) (*Block, error) { + br := bytes.NewReader(serializedBlock) + b, err := NewBlockFromReader(br) + if err != nil { + return nil, err + } + b.serializedBlock = serializedBlock + return b, nil +} + +// NewBlockFromReader returns a new instance of a bitcoin block given a +// Reader to deserialize the block. See Block. +func NewBlockFromReader(r io.Reader) (*Block, error) { // Deserialize the bytes into a MsgBlock. var msgBlock btcwire.MsgBlock - br := bytes.NewReader(serializedBlock) - err := msgBlock.Deserialize(br) + err := msgBlock.Deserialize(r) if err != nil { return nil, err } b := Block{ - msgBlock: &msgBlock, - serializedBlock: serializedBlock, - blockHeight: BlockHeightUnknown, + msgBlock: &msgBlock, + blockHeight: BlockHeightUnknown, } return &b, nil } diff --git a/tx.go b/tx.go index 1660bf0..30afb35 100644 --- a/tx.go +++ b/tx.go @@ -7,6 +7,7 @@ package btcutil import ( "bytes" "github.com/conformal/btcwire" + "io" ) // TxIndexUnknown is the value returned for a transaction index that is unknown. @@ -19,10 +20,9 @@ const TxIndexUnknown = -1 // transaction on its first access so subsequent accesses don't have to repeat // the relatively expensive hashing operations. type Tx struct { - msgTx *btcwire.MsgTx // Underlying MsgTx - serializedTx []byte // Serialized bytes for the transaction - txSha *btcwire.ShaHash // Cached transaction hash - txIndex int // Position within a block or TxIndexUnknown + msgTx *btcwire.MsgTx // Underlying MsgTx + txSha *btcwire.ShaHash // Cached transaction hash + txIndex int // Position within a block or TxIndexUnknown } // MsgTx returns the underlying btcwire.MsgTx for the transaction. @@ -72,18 +72,23 @@ func NewTx(msgTx *btcwire.MsgTx) *Tx { // NewTxFromBytes returns a new instance of a bitcoin transaction given the // serialized bytes. See Tx. func NewTxFromBytes(serializedTx []byte) (*Tx, error) { + br := bytes.NewReader(serializedTx) + return NewTxFromReader(br) +} + +// NewTxFromReader returns a new instance of a bitcoin transaction given a +// Reader to deserialize the transaction. See Tx. +func NewTxFromReader(r io.Reader) (*Tx, error) { // Deserialize the bytes into a MsgTx. var msgTx btcwire.MsgTx - br := bytes.NewReader(serializedTx) - err := msgTx.Deserialize(br) + err := msgTx.Deserialize(r) if err != nil { return nil, err } t := Tx{ - msgTx: &msgTx, - serializedTx: serializedTx, - txIndex: TxIndexUnknown, + msgTx: &msgTx, + txIndex: TxIndexUnknown, } return &t, nil }