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
This commit is contained in:
Josh Rickmar 2014-06-23 22:01:21 -05:00
parent 9a3f83d493
commit b3e031c1f9
2 changed files with 30 additions and 14 deletions

View file

@ -8,6 +8,7 @@ import (
"bytes" "bytes"
"fmt" "fmt"
"github.com/conformal/btcwire" "github.com/conformal/btcwire"
"io"
) )
// OutOfRangeError describes an error due to accessing an element that is out // 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 // NewBlockFromBytes returns a new instance of a bitcoin block given the
// serialized bytes. See Block. // serialized bytes. See Block.
func NewBlockFromBytes(serializedBlock []byte) (*Block, error) { 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. // Deserialize the bytes into a MsgBlock.
var msgBlock btcwire.MsgBlock var msgBlock btcwire.MsgBlock
br := bytes.NewReader(serializedBlock) err := msgBlock.Deserialize(r)
err := msgBlock.Deserialize(br)
if err != nil { if err != nil {
return nil, err return nil, err
} }
b := Block{ b := Block{
msgBlock: &msgBlock, msgBlock: &msgBlock,
serializedBlock: serializedBlock, blockHeight: BlockHeightUnknown,
blockHeight: BlockHeightUnknown,
} }
return &b, nil return &b, nil
} }

23
tx.go
View file

@ -7,6 +7,7 @@ package btcutil
import ( import (
"bytes" "bytes"
"github.com/conformal/btcwire" "github.com/conformal/btcwire"
"io"
) )
// TxIndexUnknown is the value returned for a transaction index that is unknown. // 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 // transaction on its first access so subsequent accesses don't have to repeat
// the relatively expensive hashing operations. // the relatively expensive hashing operations.
type Tx struct { type Tx struct {
msgTx *btcwire.MsgTx // Underlying MsgTx msgTx *btcwire.MsgTx // Underlying MsgTx
serializedTx []byte // Serialized bytes for the transaction txSha *btcwire.ShaHash // Cached transaction hash
txSha *btcwire.ShaHash // Cached transaction hash txIndex int // Position within a block or TxIndexUnknown
txIndex int // Position within a block or TxIndexUnknown
} }
// MsgTx returns the underlying btcwire.MsgTx for the transaction. // 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 // NewTxFromBytes returns a new instance of a bitcoin transaction given the
// serialized bytes. See Tx. // serialized bytes. See Tx.
func NewTxFromBytes(serializedTx []byte) (*Tx, error) { 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. // Deserialize the bytes into a MsgTx.
var msgTx btcwire.MsgTx var msgTx btcwire.MsgTx
br := bytes.NewReader(serializedTx) err := msgTx.Deserialize(r)
err := msgTx.Deserialize(br)
if err != nil { if err != nil {
return nil, err return nil, err
} }
t := Tx{ t := Tx{
msgTx: &msgTx, msgTx: &msgTx,
serializedTx: serializedTx, txIndex: TxIndexUnknown,
txIndex: TxIndexUnknown,
} }
return &t, nil return &t, nil
} }