diff --git a/txsort/txsort.go b/txsort/txsort.go index b915cb5..9a32036 100644 --- a/txsort/txsort.go +++ b/txsort/txsort.go @@ -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. diff --git a/txsort/txsort_test.go b/txsort/txsort_test.go index ef5db18..bcf6d2b 100644 --- a/txsort/txsort_test.go +++ b/txsort/txsort_test.go @@ -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 + } } }