Add new Tx wrapper for btcwire.MsgTx.
Currently, transaction hash caching is provided via Block directly, but a transaction is not always part of a block and there are several cases where only the transaction needs to be dealt with without wanting to pass the entire block and transaction index around to be able to get at the cached hash. So, this commit adds a new type named Tx which is a wrapper that provides easier and more efficient manipulation of raw wire protocol transactions. It memoizes the hash for the transaction on its first access so subsequent accesses don't have to repeat the relatively expensive hashing operations. The idea is the callers can pass around pointers to these Tx types instead of raw btcwire.MsgTx pointers. For now, the Block API has not been changed, but the plan is to change it to provide access to these wrapped transactions rather than having it do the transaction hash caching directly. This is only the first part of a series of changes working towards optimizations noted in conformal/btcd#25.
This commit is contained in:
parent
f72ab9cfce
commit
e402c62673
2 changed files with 96 additions and 0 deletions
7
doc.go
7
doc.go
|
@ -12,6 +12,13 @@ manipulation of raw wire protocol blocks. It also memoizes hashes for the
|
|||
block and its transactions on their first access so subsequent accesses don't
|
||||
have to repeat the relatively expensive hashing operations.
|
||||
|
||||
Tx Overview
|
||||
|
||||
A Tx defines a bitcoin transaction that provides more efficient manipulation of
|
||||
raw wire protocol transactions. It memoizes the hash for the transaction on its
|
||||
first access so subsequent accesses don't have to repeat the relatively
|
||||
expensive hashing operations.
|
||||
|
||||
Base58 Usage
|
||||
|
||||
To decode a base58 string:
|
||||
|
|
89
tx.go
Normal file
89
tx.go
Normal file
|
@ -0,0 +1,89 @@
|
|||
// Copyright (c) 2013 Conformal Systems LLC.
|
||||
// Use of this source code is governed by an ISC
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package btcutil
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"github.com/conformal/btcwire"
|
||||
)
|
||||
|
||||
// TxIndexUnknown is the value returned for a transaction index that is unknown.
|
||||
// This is typically because the transaction has not been inserted into a block
|
||||
// yet.
|
||||
const TxIndexUnknown = -1
|
||||
|
||||
// Tx defines a bitcoin transaction that provides easier and more efficient
|
||||
// manipulation of raw transactions. It also memoizes the hash for the
|
||||
// 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 returns the underlying btcwire.MsgTx for the transaction.
|
||||
func (t *Tx) MsgTx() *btcwire.MsgTx {
|
||||
// Return the cached transaction.
|
||||
return t.msgTx
|
||||
}
|
||||
|
||||
// Sha returns the hash of the transaction. This is equivalent to
|
||||
// calling TxSha on the underlying btcwire.MsgTx, however it caches the
|
||||
// result so subsequent calls are more efficient.
|
||||
func (t *Tx) Sha() *btcwire.ShaHash {
|
||||
// Return the cached hash if it has already been generated.
|
||||
if t.txSha != nil {
|
||||
return t.txSha
|
||||
}
|
||||
|
||||
// Generate the transaction hash. Ignore the error since TxSha can't
|
||||
// currently fail.
|
||||
sha, _ := t.msgTx.TxSha()
|
||||
|
||||
// Cache the hash and return it.
|
||||
t.txSha = &sha
|
||||
return &sha
|
||||
}
|
||||
|
||||
// Index returns the saved index of the transaction within a block. This value
|
||||
// will be TxIndexUnknown if it hasn't already explicitly been set.
|
||||
func (t *Tx) Index() int {
|
||||
return t.txIndex
|
||||
}
|
||||
|
||||
// SetIndex sets the index of the transaction in within a block.
|
||||
func (t *Tx) SetIndex(index int) {
|
||||
t.txIndex = index
|
||||
}
|
||||
|
||||
// NewTx returns a new instance of a bitcoin transaction given an underlying
|
||||
// btcwire.MsgTx. See Tx.
|
||||
func NewTx(msgTx *btcwire.MsgTx) *Tx {
|
||||
return &Tx{
|
||||
msgTx: msgTx,
|
||||
txIndex: TxIndexUnknown,
|
||||
}
|
||||
}
|
||||
|
||||
// NewTxFromBytes returns a new instance of a bitcoin transaction given the
|
||||
// serialized bytes. See Tx.
|
||||
func NewTxFromBytes(serializedTx []byte) (*Tx, error) {
|
||||
// Deserialize the bytes into a MsgTx.
|
||||
var msgTx btcwire.MsgTx
|
||||
br := bytes.NewBuffer(serializedTx)
|
||||
err := msgTx.Deserialize(br)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
t := Tx{
|
||||
msgTx: &msgTx,
|
||||
serializedTx: serializedTx,
|
||||
txIndex: TxIndexUnknown,
|
||||
}
|
||||
return &t, nil
|
||||
}
|
Loading…
Add table
Reference in a new issue