github.com/decred/dcrlnd@v0.7.6/lnwallet/commit_sort_test.go (about)

     1  package lnwallet_test
     2  
     3  import (
     4  	"reflect"
     5  	"testing"
     6  
     7  	"github.com/decred/dcrd/wire"
     8  	"github.com/decred/dcrlnd/lnwallet"
     9  )
    10  
    11  type commitSortTest struct {
    12  	name     string
    13  	tx       *wire.MsgTx
    14  	cltvs    []uint32
    15  	intrans  map[int]int // input transformation
    16  	outtrans map[int]int // output transformation
    17  }
    18  
    19  func (t *commitSortTest) expTxIns() []*wire.TxIn {
    20  	if len(t.intrans) == 0 {
    21  		return nil
    22  	}
    23  
    24  	expTxIns := make([]*wire.TxIn, len(t.intrans))
    25  	for start, end := range t.intrans {
    26  		expTxIns[end] = t.tx.TxIn[start]
    27  	}
    28  
    29  	return expTxIns
    30  }
    31  
    32  func (t *commitSortTest) expTxOuts() []*wire.TxOut {
    33  	if len(t.outtrans) == 0 {
    34  		return nil
    35  	}
    36  
    37  	expTxOuts := make([]*wire.TxOut, len(t.outtrans))
    38  	for start, end := range t.outtrans {
    39  		expTxOuts[end] = t.tx.TxOut[start]
    40  	}
    41  
    42  	return expTxOuts
    43  }
    44  
    45  var commitSortTests = []commitSortTest{
    46  	{
    47  		name: "sort inputs on prevoutpoint txid",
    48  		tx: &wire.MsgTx{
    49  			TxIn: []*wire.TxIn{
    50  				{
    51  					PreviousOutPoint: wire.OutPoint{
    52  						Hash: [32]byte{0x01},
    53  					},
    54  				},
    55  				{
    56  					PreviousOutPoint: wire.OutPoint{
    57  						Hash: [32]byte{0x00},
    58  					},
    59  				},
    60  			},
    61  		},
    62  		intrans: map[int]int{
    63  			0: 1,
    64  			1: 0,
    65  		},
    66  	},
    67  	{
    68  		name: "sort inputs on prevoutpoint index",
    69  		tx: &wire.MsgTx{
    70  			TxIn: []*wire.TxIn{
    71  				{
    72  					PreviousOutPoint: wire.OutPoint{
    73  						Index: 1,
    74  					},
    75  				},
    76  				{
    77  					PreviousOutPoint: wire.OutPoint{
    78  						Index: 0,
    79  					},
    80  				},
    81  			},
    82  		},
    83  		intrans: map[int]int{
    84  			0: 1,
    85  			1: 0,
    86  		},
    87  	},
    88  	{
    89  		name: "inputs already sorted",
    90  		tx: &wire.MsgTx{
    91  			TxIn: []*wire.TxIn{
    92  				{
    93  					PreviousOutPoint: wire.OutPoint{
    94  						Index: 0,
    95  					},
    96  				},
    97  				{
    98  					PreviousOutPoint: wire.OutPoint{
    99  						Index: 1,
   100  					},
   101  				},
   102  			},
   103  		},
   104  		intrans: map[int]int{
   105  			0: 0,
   106  			1: 1,
   107  		},
   108  	},
   109  	{
   110  		name: "sort outputs on value",
   111  		tx: &wire.MsgTx{
   112  			TxOut: []*wire.TxOut{
   113  				{
   114  					Value:    2,
   115  					PkScript: []byte{0x0},
   116  				},
   117  				{
   118  					Value:    1,
   119  					PkScript: []byte{0x0},
   120  				},
   121  			},
   122  		},
   123  		cltvs: []uint32{0, 0},
   124  		outtrans: map[int]int{
   125  			0: 1,
   126  			1: 0,
   127  		},
   128  	},
   129  	{
   130  		name: "sort outputs on pkscript",
   131  		tx: &wire.MsgTx{
   132  			TxOut: []*wire.TxOut{
   133  				{
   134  					Value:    1,
   135  					PkScript: []byte{0x2},
   136  				},
   137  				{
   138  					Value:    1,
   139  					PkScript: []byte{0x1},
   140  				},
   141  			},
   142  		},
   143  		cltvs: []uint32{0, 0},
   144  		outtrans: map[int]int{
   145  			0: 1,
   146  			1: 0,
   147  		},
   148  	},
   149  	{
   150  		name: "sort outputs on cltv",
   151  		tx: &wire.MsgTx{
   152  			TxOut: []*wire.TxOut{
   153  				{
   154  					Value:    1,
   155  					PkScript: []byte{0x1},
   156  				},
   157  				{
   158  					Value:    1,
   159  					PkScript: []byte{0x1},
   160  				},
   161  			},
   162  		},
   163  		cltvs: []uint32{2, 1},
   164  		outtrans: map[int]int{
   165  			0: 1,
   166  			1: 0,
   167  		},
   168  	},
   169  	{
   170  		name: "sort complex outputs",
   171  		tx: &wire.MsgTx{
   172  			TxOut: []*wire.TxOut{
   173  				{
   174  					Value:    100000,
   175  					PkScript: []byte{0x01, 0x02},
   176  				},
   177  				{
   178  					Value:    200000,
   179  					PkScript: []byte{0x03, 0x02},
   180  				},
   181  				{
   182  					Value:    1000,
   183  					PkScript: []byte{0x03},
   184  				},
   185  				{
   186  					Value:    1000,
   187  					PkScript: []byte{0x02},
   188  				},
   189  				{
   190  					Value:    1000,
   191  					PkScript: []byte{0x1},
   192  				},
   193  				{
   194  					Value:    1000,
   195  					PkScript: []byte{0x1},
   196  				},
   197  			},
   198  		},
   199  		cltvs: []uint32{0, 0, 100, 90, 70, 80},
   200  		outtrans: map[int]int{
   201  			0: 4,
   202  			1: 5,
   203  			2: 3,
   204  			3: 2,
   205  			4: 0,
   206  			5: 1,
   207  		},
   208  	},
   209  	{
   210  		name: "outputs already sorted",
   211  		tx: &wire.MsgTx{
   212  			TxOut: []*wire.TxOut{
   213  				{
   214  					Value:    1,
   215  					PkScript: []byte{0x1},
   216  				},
   217  				{
   218  					Value:    1,
   219  					PkScript: []byte{0x1},
   220  				},
   221  			},
   222  		},
   223  		cltvs: []uint32{1, 2},
   224  		outtrans: map[int]int{
   225  			0: 0,
   226  			1: 1,
   227  		},
   228  	},
   229  }
   230  
   231  // TestCommitSort asserts that the outputs of a transaction are properly sorted
   232  // using InPlaceCommitSort. The outputs should always be sorted by value, then
   233  // lexicographically by pkscript, and then CLTV value.
   234  func TestCommitSort(t *testing.T) {
   235  	for _, test := range commitSortTests {
   236  		t.Run(test.name, func(t *testing.T) {
   237  			expTxIns := test.expTxIns()
   238  			expTxOuts := test.expTxOuts()
   239  
   240  			lnwallet.InPlaceCommitSort(test.tx, test.cltvs)
   241  
   242  			if !reflect.DeepEqual(test.tx.TxIn, expTxIns) {
   243  				t.Fatalf("commit inputs mismatch, want: %v, "+
   244  					"got: %v", expTxIns, test.tx.TxIn)
   245  			}
   246  
   247  			if !reflect.DeepEqual(test.tx.TxOut, expTxOuts) {
   248  				t.Fatalf("commit outputs mismatch, want: %v, "+
   249  					"got: %v", expTxOuts, test.tx.TxOut)
   250  			}
   251  		})
   252  	}
   253  }