txsort: Add InPlaceSort function.

This adds a new function with loud warnings which allows sorting a
transaction in place by mutating it.  This is more efficient for the
caller if they are the ones creating the transaction and are sure it
will not invalid any cache or containing structures.

The Sort function which makes a copy and is therefore does not mutate
the passed transaction is still available and the default method.
This commit is contained in:
Dave Collins 2015-10-23 04:42:59 -05:00
parent e0e9257790
commit 0df67ee064
2 changed files with 27 additions and 0 deletions

View file

@ -14,6 +14,23 @@ import (
"github.com/btcsuite/btcd/wire"
)
// InPlaceSort modifies the passed transaction inputs and outputs to be sorted
// based on BIP LI01.
//
// WARNING: This function must NOT be called with published transactions since
// it will mutate the transaction if it's not already sorted. This can cause
// issues if you mutate a tx in a block, for example, which would invalidate the
// block. It could also cause cached hashes, such as in a btcutil.Tx to become
// invalidated.
//
// The function should only be used if the caller is creating the transaction or
// is otherwise 100% positive mutating will not cause adverse affects due to
// other dependencies.
func InPlaceSort(tx *wire.MsgTx) {
sort.Sort(sortableInputSlice(tx.TxIn))
sort.Sort(sortableOutputSlice(tx.TxOut))
}
// Sort returns a new transaction with the inputs and outputs sorted based on
// BIP LI01. The passed transaction is not modified and the new transaction
// might have a different hash if any sorting was done.

View file

@ -110,5 +110,15 @@ func TestSort(t *testing.T) {
test.unsortedHash)
continue
}
// Now sort the transaction using the mutable version and ensure
// the resulting hash is the expected value.
txsort.InPlaceSort(&tx)
if got := tx.TxSha().String(); got != test.sortedHash {
t.Errorf("SortMutate (%s): sorted hash does not match "+
"expected - got %v, want %v", test.name, got,
test.sortedHash)
continue
}
}
}