OSDN Git Service

edht tx txoutput (#1966)
[bytom/bytom.git] / wallet / utxo_test.go
1 package wallet
2
3 import (
4         "encoding/hex"
5         "encoding/json"
6         "fmt"
7         "os"
8         "sort"
9         "testing"
10
11         "github.com/bytom/bytom/account"
12         "github.com/bytom/bytom/consensus"
13         dbm "github.com/bytom/bytom/database/leveldb"
14         "github.com/bytom/bytom/protocol/bc"
15         "github.com/bytom/bytom/protocol/bc/types"
16         "github.com/bytom/bytom/testutil"
17 )
18
19 func TestGetAccountUtxos(t *testing.T) {
20         testDB := dbm.NewDB("testdb", "leveldb", "temp")
21         defer os.RemoveAll("temp")
22
23         cases := []struct {
24                 dbUtxos          map[string]*account.UTXO
25                 unconfirmedUtxos []*account.UTXO
26                 id               string
27                 unconfirmed      bool
28                 isSmartContract  bool
29                 wantUtxos        []*account.UTXO
30         }{
31                 {
32                         dbUtxos:         map[string]*account.UTXO{},
33                         id:              "",
34                         unconfirmed:     false,
35                         isSmartContract: false,
36                         wantUtxos:       []*account.UTXO{},
37                 },
38                 {
39                         dbUtxos: map[string]*account.UTXO{
40                                 string(account.StandardUTXOKey(bc.Hash{V0: 1})): &account.UTXO{
41                                         OutputID: bc.Hash{V0: 1},
42                                 },
43                                 string(account.StandardUTXOKey(bc.Hash{V0: 2})): &account.UTXO{
44                                         OutputID: bc.Hash{V0: 2},
45                                 },
46                                 string(account.StandardUTXOKey(bc.Hash{V0: 3})): &account.UTXO{
47                                         OutputID: bc.Hash{V0: 3},
48                                 },
49                                 string(account.ContractUTXOKey(bc.Hash{V0: 4})): &account.UTXO{
50                                         OutputID: bc.Hash{V0: 4},
51                                 },
52                         },
53                         unconfirmedUtxos: []*account.UTXO{},
54                         id:               "",
55                         isSmartContract:  false,
56                         wantUtxos: []*account.UTXO{
57                                 &account.UTXO{OutputID: bc.Hash{V0: 1}},
58                                 &account.UTXO{OutputID: bc.Hash{V0: 2}},
59                                 &account.UTXO{OutputID: bc.Hash{V0: 3}},
60                         },
61                 },
62                 {
63                         dbUtxos: map[string]*account.UTXO{
64                                 string(account.StandardUTXOKey(bc.Hash{V0: 1})): &account.UTXO{
65                                         OutputID: bc.Hash{V0: 1},
66                                 },
67                                 string(account.StandardUTXOKey(bc.Hash{V0: 2})): &account.UTXO{
68                                         OutputID: bc.Hash{V0: 2},
69                                 },
70                                 string(account.StandardUTXOKey(bc.Hash{V0: 3})): &account.UTXO{
71                                         OutputID: bc.Hash{V0: 3},
72                                 },
73                                 string(account.ContractUTXOKey(bc.Hash{V0: 4})): &account.UTXO{
74                                         OutputID: bc.Hash{V0: 4},
75                                 },
76                         },
77                         unconfirmedUtxos: []*account.UTXO{
78                                 &account.UTXO{
79                                         OutputID:       bc.Hash{V0: 5},
80                                         ControlProgram: []byte("smart contract"),
81                                 },
82                         },
83                         id:              "",
84                         unconfirmed:     false,
85                         isSmartContract: true,
86                         wantUtxos: []*account.UTXO{
87                                 &account.UTXO{OutputID: bc.Hash{V0: 4}},
88                         },
89                 },
90                 {
91                         dbUtxos: map[string]*account.UTXO{
92                                 string(account.StandardUTXOKey(bc.Hash{V0: 1})): &account.UTXO{
93                                         OutputID: bc.Hash{V0: 1},
94                                 },
95                                 string(account.StandardUTXOKey(bc.Hash{V0: 1, V1: 2})): &account.UTXO{
96                                         OutputID: bc.Hash{V0: 1, V1: 2},
97                                 },
98                                 string(account.StandardUTXOKey(bc.Hash{V0: 2})): &account.UTXO{
99                                         OutputID: bc.Hash{V0: 2},
100                                 },
101                                 string(account.StandardUTXOKey(bc.Hash{V0: 2, V1: 2})): &account.UTXO{
102                                         OutputID: bc.Hash{V0: 2, V1: 2},
103                                 },
104                         },
105                         unconfirmedUtxos: []*account.UTXO{
106                                 &account.UTXO{
107                                         OutputID:       bc.Hash{V0: 6},
108                                         ControlProgram: []byte{0x51},
109                                 },
110                         },
111                         id:              "0000000000000002",
112                         unconfirmed:     false,
113                         isSmartContract: false,
114                         wantUtxos: []*account.UTXO{
115                                 &account.UTXO{OutputID: bc.Hash{V0: 2}},
116                                 &account.UTXO{OutputID: bc.Hash{V0: 2, V1: 2}},
117                         },
118                 },
119                 {
120                         dbUtxos: map[string]*account.UTXO{
121                                 string(account.StandardUTXOKey(bc.Hash{V0: 3})): &account.UTXO{
122                                         OutputID: bc.Hash{V0: 3},
123                                 },
124                                 string(account.ContractUTXOKey(bc.Hash{V0: 4})): &account.UTXO{
125                                         OutputID: bc.Hash{V0: 4},
126                                 },
127                         },
128                         unconfirmedUtxos: []*account.UTXO{
129                                 &account.UTXO{
130                                         OutputID:       bc.Hash{V0: 5},
131                                         ControlProgram: []byte("smart contract"),
132                                 },
133                                 &account.UTXO{
134                                         OutputID:       bc.Hash{V0: 6},
135                                         ControlProgram: []byte{0x51},
136                                 },
137                         },
138                         id:              "",
139                         unconfirmed:     true,
140                         isSmartContract: true,
141                         wantUtxos: []*account.UTXO{
142                                 &account.UTXO{
143                                         OutputID:       bc.Hash{V0: 5},
144                                         ControlProgram: []byte("smart contract"),
145                                 },
146                                 &account.UTXO{
147                                         OutputID: bc.Hash{V0: 4},
148                                 },
149                         },
150                 },
151                 {
152                         dbUtxos: map[string]*account.UTXO{
153                                 string(account.StandardUTXOKey(bc.Hash{V0: 3})): &account.UTXO{
154                                         OutputID: bc.Hash{V0: 3},
155                                 },
156                                 string(account.ContractUTXOKey(bc.Hash{V0: 4})): &account.UTXO{
157                                         OutputID: bc.Hash{V0: 4},
158                                 },
159                         },
160                         unconfirmedUtxos: []*account.UTXO{
161                                 &account.UTXO{
162                                         OutputID:       bc.Hash{V0: 5},
163                                         ControlProgram: []byte("smart contract"),
164                                 },
165                                 &account.UTXO{
166                                         OutputID:       bc.Hash{V0: 6},
167                                         ControlProgram: []byte{0x51},
168                                 },
169                         },
170                         id:              "",
171                         unconfirmed:     true,
172                         isSmartContract: false,
173                         wantUtxos: []*account.UTXO{
174                                 &account.UTXO{
175                                         OutputID:       bc.Hash{V0: 6},
176                                         ControlProgram: []byte{0x51},
177                                 },
178                                 &account.UTXO{
179                                         OutputID: bc.Hash{V0: 3},
180                                 },
181                         },
182                 },
183         }
184
185         w := &Wallet{DB: testDB}
186         for i, c := range cases {
187                 for k, u := range c.dbUtxos {
188                         data, err := json.Marshal(u)
189                         if err != nil {
190                                 t.Error(err)
191                         }
192                         testDB.Set([]byte(k), data)
193                 }
194
195                 w.AccountMgr = account.NewManager(testDB, nil)
196                 w.AccountMgr.AddUnconfirmedUtxo(c.unconfirmedUtxos)
197                 gotUtxos := w.GetAccountUtxos("", c.id, c.unconfirmed, c.isSmartContract)
198                 if !testutil.DeepEqual(gotUtxos, c.wantUtxos) {
199                         t.Errorf("case %d: got %v want %v", i, gotUtxos, c.wantUtxos)
200                 }
201
202                 for k := range c.dbUtxos {
203                         testDB.Delete([]byte(k))
204                 }
205         }
206 }
207
208 //because can not pass by btm2.0 branch
209 func TestFilterAccountUtxo(t *testing.T) {
210         testDB := dbm.NewDB("testdb", "leveldb", "temp")
211         defer os.RemoveAll("temp")
212
213         cases := []struct {
214                 dbPrograms map[string]*account.CtrlProgram
215                 input      []*account.UTXO
216                 wantUtxos  []*account.UTXO
217         }{
218                 {
219                         dbPrograms: map[string]*account.CtrlProgram{},
220                         input:      []*account.UTXO{},
221                         wantUtxos:  []*account.UTXO{},
222                 },
223                 {
224                         dbPrograms: map[string]*account.CtrlProgram{
225                                 "436f6e74726163743a2a37a64a4e15a772ab43bf3f5956d0d1f353946496788e7f40d0ff1796286a6f": &account.CtrlProgram{
226                                         AccountID: "testAccount",
227                                         Address:   "testAddress",
228                                         KeyIndex:  53,
229                                         Change:    true,
230                                 },
231                         },
232                         input: []*account.UTXO{
233                                 &account.UTXO{
234                                         ControlProgram: []byte{0x00, 0x14, 0x62, 0x50, 0x18, 0xb6, 0x85, 0x77, 0xba, 0x9b, 0x26, 0x19, 0xc8, 0x1d, 0x2e, 0x96, 0xba, 0x22, 0xbe, 0x77, 0x77, 0xd7},
235                                         AssetID:        bc.AssetID{V0: 1},
236                                         Amount:         3,
237                                 },
238                                 &account.UTXO{
239                                         ControlProgram: []byte{0x91},
240                                         AssetID:        bc.AssetID{V0: 1},
241                                         Amount:         4,
242                                 },
243                         },
244                         wantUtxos: []*account.UTXO{
245                                 &account.UTXO{
246                                         ControlProgram:      []byte{0x00, 0x14, 0x62, 0x50, 0x18, 0xb6, 0x85, 0x77, 0xba, 0x9b, 0x26, 0x19, 0xc8, 0x1d, 0x2e, 0x96, 0xba, 0x22, 0xbe, 0x77, 0x77, 0xd7},
247                                         AssetID:             bc.AssetID{V0: 1},
248                                         Amount:              3,
249                                         AccountID:           "testAccount",
250                                         Address:             "testAddress",
251                                         ControlProgramIndex: 53,
252                                         Change:              true,
253                                 },
254                         },
255                 },
256                 {
257                         dbPrograms: map[string]*account.CtrlProgram{},
258                         input: []*account.UTXO{
259                                 &account.UTXO{
260                                         ControlProgram: []byte{0x00, 0x14, 0x62, 0x50, 0x18, 0xb6, 0x85, 0x77, 0xba, 0x9b, 0x26, 0x19, 0xc8, 0x1d, 0x2e, 0x96, 0xba, 0x22, 0xbe, 0x77, 0x77, 0xd7},
261                                         AssetID:        bc.AssetID{V0: 1},
262                                         Amount:         3,
263                                 },
264                                 &account.UTXO{
265                                         ControlProgram: []byte{0x91},
266                                         AssetID:        bc.AssetID{V0: 1},
267                                         Amount:         3,
268                                 },
269                         },
270                         wantUtxos: []*account.UTXO{},
271                 },
272                 {
273                         dbPrograms: map[string]*account.CtrlProgram{
274                                 "436f6e74726163743a2a37a64a4e15a772ab43bf3f5956d0d1f353946496788e7f40d0ff1796286a6f": &account.CtrlProgram{
275                                         AccountID: "testAccount",
276                                         Address:   "testAddress",
277                                         KeyIndex:  53,
278                                         Change:    true,
279                                 },
280                                 "436f6e74726163743adb4d86262c12ba70d50b3ca3ae102d5682436243bd1e8c79569603f75675036a": &account.CtrlProgram{
281                                         AccountID: "testAccount2",
282                                         Address:   "testAddress2",
283                                         KeyIndex:  72,
284                                         Change:    false,
285                                 },
286                         },
287                         input: []*account.UTXO{
288                                 &account.UTXO{
289                                         ControlProgram: []byte{0x00, 0x14, 0x62, 0x50, 0x18, 0xb6, 0x85, 0x77, 0xba, 0x9b, 0x26, 0x19, 0xc8, 0x1d, 0x2e, 0x96, 0xba, 0x22, 0xbe, 0x77, 0x77, 0xd7},
290                                         AssetID:        bc.AssetID{V0: 1},
291                                         Amount:         3,
292                                 },
293                                 &account.UTXO{
294                                         ControlProgram: []byte{0x00, 0x14, 0x62, 0x50, 0x18, 0xb6, 0x85, 0x77, 0xba, 0x9b, 0x26, 0x19, 0xc8, 0x1d, 0x2e, 0x96, 0xba, 0x22, 0xbe, 0x77, 0x77, 0xd7},
295                                         AssetID:        bc.AssetID{V0: 1},
296                                         Amount:         5,
297                                 },
298                                 &account.UTXO{
299                                         ControlProgram: []byte{0x00, 0x14, 0xc6, 0xbf, 0x22, 0x19, 0x64, 0x2a, 0xc5, 0x9e, 0x5b, 0xe4, 0xeb, 0xdf, 0x5b, 0x22, 0x49, 0x56, 0xa7, 0x98, 0xa4, 0xdf},
300                                         AssetID:        bc.AssetID{V0: 1},
301                                         Amount:         7,
302                                 },
303                         },
304                         wantUtxos: []*account.UTXO{
305                                 &account.UTXO{
306                                         ControlProgram:      []byte{0x00, 0x14, 0x62, 0x50, 0x18, 0xb6, 0x85, 0x77, 0xba, 0x9b, 0x26, 0x19, 0xc8, 0x1d, 0x2e, 0x96, 0xba, 0x22, 0xbe, 0x77, 0x77, 0xd7},
307                                         AssetID:             bc.AssetID{V0: 1},
308                                         Amount:              3,
309                                         AccountID:           "testAccount",
310                                         Address:             "testAddress",
311                                         ControlProgramIndex: 53,
312                                         Change:              true,
313                                 },
314                                 &account.UTXO{
315                                         ControlProgram:      []byte{0x00, 0x14, 0x62, 0x50, 0x18, 0xb6, 0x85, 0x77, 0xba, 0x9b, 0x26, 0x19, 0xc8, 0x1d, 0x2e, 0x96, 0xba, 0x22, 0xbe, 0x77, 0x77, 0xd7},
316                                         AssetID:             bc.AssetID{V0: 1},
317                                         Amount:              5,
318                                         AccountID:           "testAccount",
319                                         Address:             "testAddress",
320                                         ControlProgramIndex: 53,
321                                         Change:              true,
322                                 },
323                                 &account.UTXO{
324                                         ControlProgram:      []byte{0x00, 0x14, 0xc6, 0xbf, 0x22, 0x19, 0x64, 0x2a, 0xc5, 0x9e, 0x5b, 0xe4, 0xeb, 0xdf, 0x5b, 0x22, 0x49, 0x56, 0xa7, 0x98, 0xa4, 0xdf},
325                                         AssetID:             bc.AssetID{V0: 1},
326                                         Amount:              7,
327                                         AccountID:           "testAccount2",
328                                         Address:             "testAddress2",
329                                         ControlProgramIndex: 72,
330                                         Change:              false,
331                                 },
332                         },
333                 },
334         }
335
336         w := &Wallet{DB: testDB}
337         for i, c := range cases {
338                 for s, p := range c.dbPrograms {
339                         data, err := json.Marshal(p)
340                         if err != nil {
341                                 t.Error(err)
342                         }
343                         key, err := hex.DecodeString(s)
344                         if err != nil {
345                                 t.Error(err)
346                         }
347                         testDB.Set(key, data)
348                 }
349                 gotUtxos := w.filterAccountUtxo(c.input)
350                 sort.Slice(gotUtxos[:], func(i, j int) bool {
351                         return gotUtxos[i].Amount < gotUtxos[j].Amount
352                 })
353
354                 if !testutil.DeepEqual(gotUtxos, c.wantUtxos) {
355                         t.Errorf("case %d: got %v want %v", i, gotUtxos, c.wantUtxos)
356                 }
357                 for s := range c.dbPrograms {
358                         key, err := hex.DecodeString(s)
359                         if err != nil {
360                                 t.Error(err)
361                         }
362                         testDB.Delete(key)
363                 }
364         }
365 }
366
367 func TestTxInToUtxos(t *testing.T) {
368         cases := []struct {
369                 tx         *types.Tx
370                 statusFail bool
371                 wantUtxos  []*account.UTXO
372         }{
373                 {
374                         tx: types.NewTx(types.TxData{
375                                 Inputs: []*types.TxInput{
376                                         types.NewCoinbaseInput([]byte{0x51}),
377                                 },
378                                 Outputs: []*types.TxOutput{
379                                         types.NewOriginalTxOutput(*consensus.BTMAssetID, 41250000000, []byte{0x51}, nil),
380                                 },
381                         }),
382                         statusFail: false,
383                         wantUtxos:  []*account.UTXO{},
384                 },
385                 {
386                         tx: types.NewTx(types.TxData{
387                                 Inputs: []*types.TxInput{
388                                         types.NewIssuanceInput([]byte{}, 4125, []byte{0x51}, [][]byte{}, []byte{}),
389                                 },
390                                 Outputs: []*types.TxOutput{
391                                         types.NewOriginalTxOutput(*consensus.BTMAssetID, 4125, []byte{0x51}, nil),
392                                 },
393                         }),
394                         statusFail: false,
395                         wantUtxos:  []*account.UTXO{},
396                 },
397                 {
398                         tx: types.NewTx(types.TxData{
399                                 Inputs: []*types.TxInput{
400                                         types.NewSpendInput([][]byte{}, bc.Hash{V0: 1}, bc.AssetID{V0: 1}, 1, 1, []byte{0x51}, nil),
401                                         types.NewSpendInput([][]byte{}, bc.Hash{V0: 2}, bc.AssetID{V0: 1}, 3, 2, []byte{0x52}, nil),
402                                         types.NewSpendInput([][]byte{}, bc.Hash{V0: 3}, *consensus.BTMAssetID, 5, 3, []byte{0x53}, nil),
403                                         types.NewSpendInput([][]byte{}, bc.Hash{V0: 4}, *consensus.BTMAssetID, 7, 4, []byte{0x54}, nil),
404                                 },
405                                 Outputs: []*types.TxOutput{
406                                         types.NewOriginalTxOutput(bc.AssetID{V0: 1}, 4, []byte{0x51}, nil),
407                                         types.NewOriginalTxOutput(*consensus.BTMAssetID, 12, []byte{0x53}, nil),
408                                 },
409                         }),
410                         statusFail: false,
411                         wantUtxos: []*account.UTXO{
412                                 &account.UTXO{
413                                         OutputID:       testutil.MustDecodeHash("d7317174b78e6efdd060f19031b9b4d8dfdc8218b8fe7d86324f8c35b9cc572c"),
414                                         AssetID:        bc.AssetID{V0: 1},
415                                         Amount:         1,
416                                         ControlProgram: []byte{0x51},
417                                         SourceID:       bc.Hash{V0: 1},
418                                         SourcePos:      1,
419                                 },
420                                 &account.UTXO{
421                                         OutputID:       testutil.MustDecodeHash("2170b5a9ed124f4c2f691292dc44cc9a5b834c286a39738aa159c646cce14d95"),
422                                         AssetID:        bc.AssetID{V0: 1},
423                                         Amount:         3,
424                                         ControlProgram: []byte{0x52},
425                                         SourceID:       bc.Hash{V0: 2},
426                                         SourcePos:      2,
427                                 },
428                                 &account.UTXO{
429                                         OutputID:       testutil.MustDecodeHash("e07a0c076fcee0faccf6fc329875c3273120faaee87d273ff1cea5c64b2fb1e3"),
430                                         AssetID:        *consensus.BTMAssetID,
431                                         Amount:         5,
432                                         ControlProgram: []byte{0x53},
433                                         SourceID:       bc.Hash{V0: 3},
434                                         SourcePos:      3,
435                                 },
436                                 &account.UTXO{
437                                         OutputID:       testutil.MustDecodeHash("30fe2e3180356a847f152ce2dabab99ebe8df97ebbf100881d9591527f9fd738"),
438                                         AssetID:        *consensus.BTMAssetID,
439                                         Amount:         7,
440                                         ControlProgram: []byte{0x54},
441                                         SourceID:       bc.Hash{V0: 4},
442                                         SourcePos:      4,
443                                 },
444                         },
445                 },
446                 {
447                         tx: types.NewTx(types.TxData{
448                                 Inputs: []*types.TxInput{
449                                         types.NewSpendInput([][]byte{}, bc.Hash{V0: 3}, *consensus.BTMAssetID, 5, 3, []byte{0x53}, nil),
450                                         types.NewSpendInput([][]byte{}, bc.Hash{V0: 4}, *consensus.BTMAssetID, 7, 4, []byte{0x54}, nil),
451                                 },
452                                 Outputs: []*types.TxOutput{
453                                         types.NewOriginalTxOutput(bc.AssetID{V0: 1}, 4, []byte{0x51}, nil),
454                                         types.NewOriginalTxOutput(*consensus.BTMAssetID, 12, []byte{0x53}, nil),
455                                 },
456                         }),
457                         statusFail: true,
458                         wantUtxos: []*account.UTXO{
459                                 &account.UTXO{
460                                         OutputID:       testutil.MustDecodeHash("e07a0c076fcee0faccf6fc329875c3273120faaee87d273ff1cea5c64b2fb1e3"),
461                                         AssetID:        *consensus.BTMAssetID,
462                                         Amount:         5,
463                                         ControlProgram: []byte{0x53},
464                                         SourceID:       bc.Hash{V0: 3},
465                                         SourcePos:      3,
466                                 },
467                                 &account.UTXO{
468                                         OutputID:       testutil.MustDecodeHash("30fe2e3180356a847f152ce2dabab99ebe8df97ebbf100881d9591527f9fd738"),
469                                         AssetID:        *consensus.BTMAssetID,
470                                         Amount:         7,
471                                         ControlProgram: []byte{0x54},
472                                         SourceID:       bc.Hash{V0: 4},
473                                         SourcePos:      4,
474                                 },
475                         },
476                 },
477         }
478
479         for i, c := range cases {
480                 if gotUtxos := txInToUtxos(c.tx); !testutil.DeepEqual(gotUtxos, c.wantUtxos) {
481                         for k, v := range gotUtxos {
482                                 data, _ := json.Marshal(v)
483                                 fmt.Println(k, string(data))
484                         }
485                         for k, v := range c.wantUtxos {
486                                 data, _ := json.Marshal(v)
487                                 fmt.Println(k, string(data))
488                         }
489
490                         t.Errorf("case %d: got %v want %v", i, gotUtxos, c.wantUtxos)
491                 }
492         }
493 }
494
495 func TestTxOutToUtxos(t *testing.T) {
496         cases := []struct {
497                 tx          *types.Tx
498                 statusFail  bool
499                 blockHeight uint64
500                 wantUtxos   []*account.UTXO
501         }{
502                 {
503                         tx: types.NewTx(types.TxData{
504                                 Inputs: []*types.TxInput{
505                                         types.NewCoinbaseInput([]byte{0x51}),
506                                 },
507                                 Outputs: []*types.TxOutput{
508                                         types.NewOriginalTxOutput(*consensus.BTMAssetID, 41250000000, []byte{0x51}, nil),
509                                 },
510                         }),
511                         statusFail:  false,
512                         blockHeight: 0,
513                         wantUtxos: []*account.UTXO{
514                                 &account.UTXO{
515                                         OutputID:       testutil.MustDecodeHash("5ad31f023737c301190026c6e97da10715d5455d9bb32ace3104454faefd2bb6"),
516                                         AssetID:        *consensus.BTMAssetID,
517                                         Amount:         41250000000,
518                                         ControlProgram: []byte{0x51},
519                                         SourceID:       bc.NewHash([32]byte{0xb4, 0x7e, 0x94, 0x31, 0x88, 0xfe, 0xd3, 0xe9, 0xac, 0x99, 0x7c, 0xfc, 0x99, 0x6d, 0xd7, 0x4d, 0x04, 0x10, 0x77, 0xcb, 0x1c, 0xf8, 0x95, 0x14, 0x00, 0xe3, 0x42, 0x00, 0x8d, 0x05, 0xec, 0xdc}),
520                                         SourcePos:      0,
521                                         ValidHeight:    100,
522                                 },
523                         },
524                 },
525                 {
526                         tx: types.NewTx(types.TxData{
527                                 Inputs: []*types.TxInput{
528                                         types.NewSpendInput([][]byte{}, bc.Hash{V0: 1}, bc.AssetID{V0: 1}, 5, 1, []byte{0x51}, nil),
529                                         types.NewSpendInput([][]byte{}, bc.Hash{V0: 2}, *consensus.BTMAssetID, 7, 1, []byte{0x51}, nil),
530                                 },
531                                 Outputs: []*types.TxOutput{
532                                         types.NewOriginalTxOutput(bc.AssetID{V0: 1}, 2, []byte{0x51}, nil),
533                                         types.NewOriginalTxOutput(bc.AssetID{V0: 1}, 3, []byte{0x52}, nil),
534                                         types.NewOriginalTxOutput(*consensus.BTMAssetID, 2, []byte{0x53}, nil),
535                                         types.NewOriginalTxOutput(*consensus.BTMAssetID, 5, []byte{0x54}, nil),
536                                 },
537                         }),
538                         statusFail:  false,
539                         blockHeight: 0,
540                         wantUtxos: []*account.UTXO{
541                                 &account.UTXO{
542                                         OutputID:       testutil.MustDecodeHash("55de32fa7e96499be625063bc4c7f66bbe5d7b60f233d3a3d7265a9501c77e96"),
543                                         AssetID:        bc.AssetID{V0: 1},
544                                         Amount:         2,
545                                         ControlProgram: []byte{0x51},
546                                         SourceID:       testutil.MustDecodeHash("c0e16f80a168dad26194f9ba5a4244d9d52e08e4636aa50aa58a5b8d65e969d4"),
547                                         SourcePos:      0,
548                                 },
549                                 &account.UTXO{
550                                         OutputID:       testutil.MustDecodeHash("f256f40aa36df9cf954fdf82d5835815adfd21579289063525c64cff59bc6d96"),
551                                         AssetID:        bc.AssetID{V0: 1},
552                                         Amount:         3,
553                                         ControlProgram: []byte{0x52},
554                                         SourceID:       testutil.MustDecodeHash("c0e16f80a168dad26194f9ba5a4244d9d52e08e4636aa50aa58a5b8d65e969d4"),
555                                         SourcePos:      1,
556                                 },
557                                 &account.UTXO{
558                                         OutputID:       testutil.MustDecodeHash("60da633ce48a8bf995a23c040c1b52d543e5818abd7fc0b0faa355cf54acbcca"),
559                                         AssetID:        *consensus.BTMAssetID,
560                                         Amount:         2,
561                                         ControlProgram: []byte{0x53},
562                                         SourceID:       testutil.MustDecodeHash("c0e16f80a168dad26194f9ba5a4244d9d52e08e4636aa50aa58a5b8d65e969d4"),
563                                         SourcePos:      2,
564                                 },
565                                 &account.UTXO{
566                                         OutputID:       testutil.MustDecodeHash("550c883fd09fdccd4a5671c698d0874de9d713fa0b194f0ddffeae8ae79b57fc"),
567                                         AssetID:        *consensus.BTMAssetID,
568                                         Amount:         5,
569                                         ControlProgram: []byte{0x54},
570                                         SourceID:       testutil.MustDecodeHash("c0e16f80a168dad26194f9ba5a4244d9d52e08e4636aa50aa58a5b8d65e969d4"),
571                                         SourcePos:      3,
572                                 },
573                         },
574                 },
575                 {
576                         tx: types.NewTx(types.TxData{
577                                 Inputs: []*types.TxInput{
578                                         types.NewSpendInput([][]byte{}, bc.Hash{V0: 1}, bc.AssetID{V0: 1}, 5, 1, []byte{0x51}, nil),
579                                         types.NewSpendInput([][]byte{}, bc.Hash{V0: 2}, *consensus.BTMAssetID, 7, 1, []byte{0x51}, nil),
580                                 },
581                                 Outputs: []*types.TxOutput{
582                                         types.NewOriginalTxOutput(bc.AssetID{V0: 1}, 2, []byte{0x51}, nil),
583                                         types.NewOriginalTxOutput(bc.AssetID{V0: 1}, 3, []byte{0x52}, nil),
584                                         types.NewOriginalTxOutput(*consensus.BTMAssetID, 2, []byte{0x53}, nil),
585                                         types.NewOriginalTxOutput(*consensus.BTMAssetID, 5, []byte{0x54}, nil),
586                                 },
587                         }),
588                         statusFail:  true,
589                         blockHeight: 0,
590                         wantUtxos: []*account.UTXO{
591                                 &account.UTXO{
592                                         OutputID:       testutil.MustDecodeHash("55de32fa7e96499be625063bc4c7f66bbe5d7b60f233d3a3d7265a9501c77e96"),
593                                         AssetID:        bc.AssetID{V0: 1},
594                                         Amount:         2,
595                                         ControlProgram: []byte{0x51},
596                                         SourceID:       testutil.MustDecodeHash("c0e16f80a168dad26194f9ba5a4244d9d52e08e4636aa50aa58a5b8d65e969d4"),
597                                         SourcePos:      0,
598                                 },
599                                 &account.UTXO{
600                                         OutputID:       testutil.MustDecodeHash("f256f40aa36df9cf954fdf82d5835815adfd21579289063525c64cff59bc6d96"),
601                                         AssetID:        bc.AssetID{V0: 1},
602                                         Amount:         3,
603                                         ControlProgram: []byte{0x52},
604                                         SourceID:       testutil.MustDecodeHash("c0e16f80a168dad26194f9ba5a4244d9d52e08e4636aa50aa58a5b8d65e969d4"),
605                                         SourcePos:      1,
606                                 },
607                                 &account.UTXO{
608                                         OutputID:       testutil.MustDecodeHash("60da633ce48a8bf995a23c040c1b52d543e5818abd7fc0b0faa355cf54acbcca"),
609                                         AssetID:        *consensus.BTMAssetID,
610                                         Amount:         2,
611                                         ControlProgram: []byte{0x53},
612                                         SourceID:       testutil.MustDecodeHash("c0e16f80a168dad26194f9ba5a4244d9d52e08e4636aa50aa58a5b8d65e969d4"),
613                                         SourcePos:      2,
614                                 },
615                                 &account.UTXO{
616                                         OutputID:       testutil.MustDecodeHash("550c883fd09fdccd4a5671c698d0874de9d713fa0b194f0ddffeae8ae79b57fc"),
617                                         AssetID:        *consensus.BTMAssetID,
618                                         Amount:         5,
619                                         ControlProgram: []byte{0x54},
620                                         SourceID:       testutil.MustDecodeHash("c0e16f80a168dad26194f9ba5a4244d9d52e08e4636aa50aa58a5b8d65e969d4"),
621                                         SourcePos:      3,
622                                 },
623                         },
624                 },
625         }
626
627         for i, c := range cases {
628                 if gotUtxos := txOutToUtxos(c.tx, c.blockHeight); !testutil.DeepEqual(gotUtxos, c.wantUtxos) {
629                         for k, v := range gotUtxos {
630                                 data, _ := json.Marshal(v)
631                                 fmt.Println("got:", k, string(data))
632                         }
633                         for k, v := range c.wantUtxos {
634                                 data, _ := json.Marshal(v)
635                                 fmt.Println("want:", k, string(data))
636                         }
637
638                         t.Errorf("case %d: got %v want %v", i, gotUtxos, c.wantUtxos)
639                 }
640         }
641 }