lnd/lnwallet/commit_sort_test.go

254 lines
4.2 KiB
Go

package lnwallet_test
import (
"reflect"
"testing"
"github.com/btcsuite/btcd/wire"
"github.com/lightningnetwork/lnd/lnwallet"
)
type commitSortTest struct {
name string
tx *wire.MsgTx
cltvs []uint32
intrans map[int]int // input transformation
outtrans map[int]int // output transformation
}
func (t *commitSortTest) expTxIns() []*wire.TxIn {
if len(t.intrans) == 0 {
return nil
}
expTxIns := make([]*wire.TxIn, len(t.intrans))
for start, end := range t.intrans {
expTxIns[end] = t.tx.TxIn[start]
}
return expTxIns
}
func (t *commitSortTest) expTxOuts() []*wire.TxOut {
if len(t.outtrans) == 0 {
return nil
}
expTxOuts := make([]*wire.TxOut, len(t.outtrans))
for start, end := range t.outtrans {
expTxOuts[end] = t.tx.TxOut[start]
}
return expTxOuts
}
var commitSortTests = []commitSortTest{
{
name: "sort inputs on prevoutpoint txid",
tx: &wire.MsgTx{
TxIn: []*wire.TxIn{
{
PreviousOutPoint: wire.OutPoint{
Hash: [32]byte{0x01},
},
},
{
PreviousOutPoint: wire.OutPoint{
Hash: [32]byte{0x00},
},
},
},
},
intrans: map[int]int{
0: 1,
1: 0,
},
},
{
name: "sort inputs on prevoutpoint index",
tx: &wire.MsgTx{
TxIn: []*wire.TxIn{
{
PreviousOutPoint: wire.OutPoint{
Index: 1,
},
},
{
PreviousOutPoint: wire.OutPoint{
Index: 0,
},
},
},
},
intrans: map[int]int{
0: 1,
1: 0,
},
},
{
name: "inputs already sorted",
tx: &wire.MsgTx{
TxIn: []*wire.TxIn{
{
PreviousOutPoint: wire.OutPoint{
Index: 0,
},
},
{
PreviousOutPoint: wire.OutPoint{
Index: 1,
},
},
},
},
intrans: map[int]int{
0: 0,
1: 1,
},
},
{
name: "sort outputs on value",
tx: &wire.MsgTx{
TxOut: []*wire.TxOut{
{
Value: 2,
PkScript: []byte{0x0},
},
{
Value: 1,
PkScript: []byte{0x0},
},
},
},
cltvs: []uint32{0, 0},
outtrans: map[int]int{
0: 1,
1: 0,
},
},
{
name: "sort outputs on pkscript",
tx: &wire.MsgTx{
TxOut: []*wire.TxOut{
{
Value: 1,
PkScript: []byte{0x2},
},
{
Value: 1,
PkScript: []byte{0x1},
},
},
},
cltvs: []uint32{0, 0},
outtrans: map[int]int{
0: 1,
1: 0,
},
},
{
name: "sort outputs on cltv",
tx: &wire.MsgTx{
TxOut: []*wire.TxOut{
{
Value: 1,
PkScript: []byte{0x1},
},
{
Value: 1,
PkScript: []byte{0x1},
},
},
},
cltvs: []uint32{2, 1},
outtrans: map[int]int{
0: 1,
1: 0,
},
},
{
name: "sort complex outputs",
tx: &wire.MsgTx{
TxOut: []*wire.TxOut{
{
Value: 100000,
PkScript: []byte{0x01, 0x02},
},
{
Value: 200000,
PkScript: []byte{0x03, 0x02},
},
{
Value: 1000,
PkScript: []byte{0x03},
},
{
Value: 1000,
PkScript: []byte{0x02},
},
{
Value: 1000,
PkScript: []byte{0x1},
},
{
Value: 1000,
PkScript: []byte{0x1},
},
},
},
cltvs: []uint32{0, 0, 100, 90, 70, 80},
outtrans: map[int]int{
0: 4,
1: 5,
2: 3,
3: 2,
4: 0,
5: 1,
},
},
{
name: "outputs already sorted",
tx: &wire.MsgTx{
TxOut: []*wire.TxOut{
{
Value: 1,
PkScript: []byte{0x1},
},
{
Value: 1,
PkScript: []byte{0x1},
},
},
},
cltvs: []uint32{1, 2},
outtrans: map[int]int{
0: 0,
1: 1,
},
},
}
// TestCommitSort asserts that the outputs of a transaction are properly sorted
// using InPlaceCommitSort. The outputs should always be sorted by value, then
// lexicographically by pkscript, and then CLTV value.
func TestCommitSort(t *testing.T) {
for _, test := range commitSortTests {
t.Run(test.name, func(t *testing.T) {
expTxIns := test.expTxIns()
expTxOuts := test.expTxOuts()
lnwallet.InPlaceCommitSort(test.tx, test.cltvs)
if !reflect.DeepEqual(test.tx.TxIn, expTxIns) {
t.Fatalf("commit inputs mismatch, want: %v, "+
"got: %v", expTxIns, test.tx.TxIn)
}
if !reflect.DeepEqual(test.tx.TxOut, expTxOuts) {
t.Fatalf("commit outputs mismatch, want: %v, "+
"got: %v", expTxOuts, test.tx.TxOut)
}
})
}
}