OSDN Git Service

update TestGetAccountUtxos
[bytom/vapor.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/vapor/account"
12         "github.com/vapor/consensus"
13         "github.com/vapor/database"
14         dbm "github.com/vapor/database/leveldb"
15         "github.com/vapor/protocol/bc"
16         "github.com/vapor/protocol/bc/types"
17         "github.com/vapor/test/mock"
18         "github.com/vapor/testutil"
19 )
20
21 func TestGetAccountUtxos(t *testing.T) {
22         testDB := dbm.NewDB("testdb", "leveldb", "temp")
23         testStore := mock.NewMockWalletStore(testDB)
24         defer func() {
25                 testDB.Close()
26                 os.RemoveAll("temp")
27         }()
28
29         cases := []struct {
30                 dbUtxos          map[string]*account.UTXO
31                 unconfirmedUtxos []*account.UTXO
32                 id               string
33                 unconfirmed      bool
34                 isSmartContract  bool
35                 wantUtxos        []*account.UTXO
36         }{
37                 {
38                         dbUtxos:         map[string]*account.UTXO{},
39                         id:              "",
40                         unconfirmed:     false,
41                         isSmartContract: false,
42                         wantUtxos:       []*account.UTXO{},
43                 },
44                 {
45                         dbUtxos: map[string]*account.UTXO{
46                                 string(database.StandardUTXOKey(bc.Hash{V0: 1})): &account.UTXO{
47                                         OutputID: bc.Hash{V0: 1},
48                                 },
49                                 string(database.StandardUTXOKey(bc.Hash{V0: 2})): &account.UTXO{
50                                         OutputID: bc.Hash{V0: 2},
51                                 },
52                                 string(database.StandardUTXOKey(bc.Hash{V0: 3})): &account.UTXO{
53                                         OutputID: bc.Hash{V0: 3},
54                                 },
55                                 string(database.ContractUTXOKey(bc.Hash{V0: 4})): &account.UTXO{
56                                         OutputID: bc.Hash{V0: 4},
57                                 },
58                         },
59                         unconfirmedUtxos: []*account.UTXO{},
60                         id:               "",
61                         isSmartContract:  false,
62                         wantUtxos: []*account.UTXO{
63                                 &account.UTXO{OutputID: bc.Hash{V0: 1}},
64                                 &account.UTXO{OutputID: bc.Hash{V0: 2}},
65                                 &account.UTXO{OutputID: bc.Hash{V0: 3}},
66                         },
67                 },
68                 {
69                         dbUtxos: map[string]*account.UTXO{
70                                 string(database.StandardUTXOKey(bc.Hash{V0: 1})): &account.UTXO{
71                                         OutputID: bc.Hash{V0: 1},
72                                 },
73                                 string(database.StandardUTXOKey(bc.Hash{V0: 2})): &account.UTXO{
74                                         OutputID: bc.Hash{V0: 2},
75                                 },
76                                 string(database.StandardUTXOKey(bc.Hash{V0: 3})): &account.UTXO{
77                                         OutputID: bc.Hash{V0: 3},
78                                 },
79                                 string(database.ContractUTXOKey(bc.Hash{V0: 4})): &account.UTXO{
80                                         OutputID: bc.Hash{V0: 4},
81                                 },
82                         },
83                         unconfirmedUtxos: []*account.UTXO{
84                                 &account.UTXO{
85                                         OutputID:       bc.Hash{V0: 5},
86                                         ControlProgram: []byte("smart contract"),
87                                 },
88                         },
89                         id:              "",
90                         unconfirmed:     false,
91                         isSmartContract: true,
92                         wantUtxos: []*account.UTXO{
93                                 &account.UTXO{OutputID: bc.Hash{V0: 4}},
94                         },
95                 },
96                 {
97                         dbUtxos: map[string]*account.UTXO{
98                                 string(database.StandardUTXOKey(bc.Hash{V0: 1})): &account.UTXO{
99                                         OutputID: bc.Hash{V0: 1},
100                                 },
101                                 string(database.StandardUTXOKey(bc.Hash{V0: 1, V1: 2})): &account.UTXO{
102                                         OutputID: bc.Hash{V0: 1, V1: 2},
103                                 },
104                                 string(database.StandardUTXOKey(bc.Hash{V0: 2})): &account.UTXO{
105                                         OutputID: bc.Hash{V0: 2},
106                                 },
107                                 string(database.StandardUTXOKey(bc.Hash{V0: 2, V1: 2})): &account.UTXO{
108                                         OutputID: bc.Hash{V0: 2, V1: 2},
109                                 },
110                         },
111                         unconfirmedUtxos: []*account.UTXO{
112                                 &account.UTXO{
113                                         OutputID:       bc.Hash{V0: 6},
114                                         ControlProgram: []byte{0x51},
115                                 },
116                         },
117                         id:              "0000000000000002",
118                         unconfirmed:     false,
119                         isSmartContract: false,
120                         wantUtxos: []*account.UTXO{
121                                 &account.UTXO{OutputID: bc.Hash{V0: 2}},
122                                 &account.UTXO{OutputID: bc.Hash{V0: 2, V1: 2}},
123                         },
124                 },
125                 {
126                         dbUtxos: map[string]*account.UTXO{
127                                 string(database.StandardUTXOKey(bc.Hash{V0: 3})): &account.UTXO{
128                                         OutputID: bc.Hash{V0: 3},
129                                 },
130                                 string(database.ContractUTXOKey(bc.Hash{V0: 4})): &account.UTXO{
131                                         OutputID: bc.Hash{V0: 4},
132                                 },
133                         },
134                         unconfirmedUtxos: []*account.UTXO{
135                                 &account.UTXO{
136                                         OutputID:       bc.Hash{V0: 5},
137                                         ControlProgram: []byte("smart contract"),
138                                 },
139                                 &account.UTXO{
140                                         OutputID:       bc.Hash{V0: 6},
141                                         ControlProgram: []byte{0x51},
142                                 },
143                         },
144                         id:              "",
145                         unconfirmed:     true,
146                         isSmartContract: true,
147                         wantUtxos: []*account.UTXO{
148                                 &account.UTXO{
149                                         OutputID:       bc.Hash{V0: 5},
150                                         ControlProgram: []byte("smart contract"),
151                                 },
152                                 &account.UTXO{
153                                         OutputID: bc.Hash{V0: 4},
154                                 },
155                         },
156                 },
157                 {
158                         dbUtxos: map[string]*account.UTXO{
159                                 string(database.StandardUTXOKey(bc.Hash{V0: 3})): &account.UTXO{
160                                         OutputID: bc.Hash{V0: 3},
161                                 },
162                                 string(database.ContractUTXOKey(bc.Hash{V0: 4})): &account.UTXO{
163                                         OutputID: bc.Hash{V0: 4},
164                                 },
165                         },
166                         unconfirmedUtxos: []*account.UTXO{
167                                 &account.UTXO{
168                                         OutputID:       bc.Hash{V0: 5},
169                                         ControlProgram: []byte("smart contract"),
170                                 },
171                                 &account.UTXO{
172                                         OutputID:       bc.Hash{V0: 6},
173                                         ControlProgram: []byte{0x51},
174                                 },
175                         },
176                         id:              "",
177                         unconfirmed:     true,
178                         isSmartContract: false,
179                         wantUtxos: []*account.UTXO{
180                                 &account.UTXO{
181                                         OutputID:       bc.Hash{V0: 6},
182                                         ControlProgram: []byte{0x51},
183                                 },
184                                 &account.UTXO{
185                                         OutputID: bc.Hash{V0: 3},
186                                 },
187                         },
188                 },
189         }
190
191         w := &Wallet{store: testStore}
192         for i, c := range cases {
193                 for k, u := range c.dbUtxos {
194                         data, err := json.Marshal(u)
195                         if err != nil {
196                                 t.Error(err)
197                         }
198                         testDB.Set([]byte(k), data)
199                 }
200
201                 acccountStore := mock.NewMockAccountStore(testDB)
202                 w.AccountMgr = account.NewManager(acccountStore, nil)
203                 w.AccountMgr.AddUnconfirmedUtxo(c.unconfirmedUtxos)
204                 gotUtxos := w.GetAccountUtxos("", c.id, c.unconfirmed, c.isSmartContract, false)
205                 if !testutil.DeepEqual(gotUtxos, c.wantUtxos) {
206                         t.Errorf("case %d: got %v want %v", i, gotUtxos, c.wantUtxos)
207                 }
208
209                 for k := range c.dbUtxos {
210                         testDB.Delete([]byte(k))
211                 }
212         }
213 }
214
215 func TestFilterAccountUtxo(t *testing.T) {
216         testDB := dbm.NewDB("testdb", "leveldb", "temp")
217         testStore := mock.NewMockWalletStore(testDB)
218         defer func() {
219                 testDB.Close()
220                 os.RemoveAll("temp")
221         }()
222
223         cases := []struct {
224                 dbPrograms map[string]*account.CtrlProgram
225                 input      []*account.UTXO
226                 wantUtxos  []*account.UTXO
227         }{
228                 {
229                         dbPrograms: map[string]*account.CtrlProgram{},
230                         input:      []*account.UTXO{},
231                         wantUtxos:  []*account.UTXO{},
232                 },
233                 {
234                         dbPrograms: map[string]*account.CtrlProgram{
235                                 "436f6e74726163743a2a37a64a4e15a772ab43bf3f5956d0d1f353946496788e7f40d0ff1796286a6f": &account.CtrlProgram{
236                                         AccountID: "testAccount",
237                                         Address:   "testAddress",
238                                         KeyIndex:  53,
239                                         Change:    true,
240                                 },
241                         },
242                         input: []*account.UTXO{
243                                 &account.UTXO{
244                                         ControlProgram: []byte{0x00, 0x14, 0x62, 0x50, 0x18, 0xb6, 0x85, 0x77, 0xba, 0x9b, 0x26, 0x19, 0xc8, 0x1d, 0x2e, 0x96, 0xba, 0x22, 0xbe, 0x77, 0x77, 0xd7},
245                                         AssetID:        bc.AssetID{V0: 1},
246                                         Amount:         3,
247                                 },
248                                 &account.UTXO{
249                                         ControlProgram: []byte{0x91},
250                                         AssetID:        bc.AssetID{V0: 1},
251                                         Amount:         4,
252                                 },
253                         },
254                         wantUtxos: []*account.UTXO{
255                                 &account.UTXO{
256                                         ControlProgram:      []byte{0x00, 0x14, 0x62, 0x50, 0x18, 0xb6, 0x85, 0x77, 0xba, 0x9b, 0x26, 0x19, 0xc8, 0x1d, 0x2e, 0x96, 0xba, 0x22, 0xbe, 0x77, 0x77, 0xd7},
257                                         AssetID:             bc.AssetID{V0: 1},
258                                         Amount:              3,
259                                         AccountID:           "testAccount",
260                                         Address:             "testAddress",
261                                         ControlProgramIndex: 53,
262                                         Change:              true,
263                                 },
264                                 &account.UTXO{
265                                         ControlProgram: []byte{0x91},
266                                         AssetID:        bc.AssetID{V0: 1},
267                                         Amount:         4,
268                                 },
269                         },
270                 },
271                 {
272                         dbPrograms: map[string]*account.CtrlProgram{},
273                         input: []*account.UTXO{
274                                 &account.UTXO{
275                                         ControlProgram: []byte{0x00, 0x14, 0x62, 0x50, 0x18, 0xb6, 0x85, 0x77, 0xba, 0x9b, 0x26, 0x19, 0xc8, 0x1d, 0x2e, 0x96, 0xba, 0x22, 0xbe, 0x77, 0x77, 0xd7},
276                                         AssetID:        bc.AssetID{V0: 1},
277                                         Amount:         3,
278                                 },
279                                 &account.UTXO{
280                                         ControlProgram: []byte{0x91},
281                                         AssetID:        bc.AssetID{V0: 1},
282                                         Amount:         3,
283                                 },
284                         },
285                         wantUtxos: []*account.UTXO{
286                                 &account.UTXO{
287                                         ControlProgram: []byte{0x91},
288                                         AssetID:        bc.AssetID{V0: 1},
289                                         Amount:         3,
290                                 },
291                         },
292                 },
293                 {
294                         dbPrograms: map[string]*account.CtrlProgram{
295                                 "436f6e74726163743a2a37a64a4e15a772ab43bf3f5956d0d1f353946496788e7f40d0ff1796286a6f": &account.CtrlProgram{
296                                         AccountID: "testAccount",
297                                         Address:   "testAddress",
298                                         KeyIndex:  53,
299                                         Change:    true,
300                                 },
301                                 "436f6e74726163743adb4d86262c12ba70d50b3ca3ae102d5682436243bd1e8c79569603f75675036a": &account.CtrlProgram{
302                                         AccountID: "testAccount2",
303                                         Address:   "testAddress2",
304                                         KeyIndex:  72,
305                                         Change:    false,
306                                 },
307                         },
308                         input: []*account.UTXO{
309                                 &account.UTXO{
310                                         ControlProgram: []byte{0x00, 0x14, 0x62, 0x50, 0x18, 0xb6, 0x85, 0x77, 0xba, 0x9b, 0x26, 0x19, 0xc8, 0x1d, 0x2e, 0x96, 0xba, 0x22, 0xbe, 0x77, 0x77, 0xd7},
311                                         AssetID:        bc.AssetID{V0: 1},
312                                         Amount:         3,
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                                 },
319                                 &account.UTXO{
320                                         ControlProgram: []byte{0x00, 0x14, 0xc6, 0xbf, 0x22, 0x19, 0x64, 0x2a, 0xc5, 0x9e, 0x5b, 0xe4, 0xeb, 0xdf, 0x5b, 0x22, 0x49, 0x56, 0xa7, 0x98, 0xa4, 0xdf},
321                                         AssetID:        bc.AssetID{V0: 1},
322                                         Amount:         7,
323                                 },
324                         },
325                         wantUtxos: []*account.UTXO{
326                                 &account.UTXO{
327                                         ControlProgram:      []byte{0x00, 0x14, 0x62, 0x50, 0x18, 0xb6, 0x85, 0x77, 0xba, 0x9b, 0x26, 0x19, 0xc8, 0x1d, 0x2e, 0x96, 0xba, 0x22, 0xbe, 0x77, 0x77, 0xd7},
328                                         AssetID:             bc.AssetID{V0: 1},
329                                         Amount:              3,
330                                         AccountID:           "testAccount",
331                                         Address:             "testAddress",
332                                         ControlProgramIndex: 53,
333                                         Change:              true,
334                                 },
335                                 &account.UTXO{
336                                         ControlProgram:      []byte{0x00, 0x14, 0x62, 0x50, 0x18, 0xb6, 0x85, 0x77, 0xba, 0x9b, 0x26, 0x19, 0xc8, 0x1d, 0x2e, 0x96, 0xba, 0x22, 0xbe, 0x77, 0x77, 0xd7},
337                                         AssetID:             bc.AssetID{V0: 1},
338                                         Amount:              5,
339                                         AccountID:           "testAccount",
340                                         Address:             "testAddress",
341                                         ControlProgramIndex: 53,
342                                         Change:              true,
343                                 },
344                                 &account.UTXO{
345                                         ControlProgram:      []byte{0x00, 0x14, 0xc6, 0xbf, 0x22, 0x19, 0x64, 0x2a, 0xc5, 0x9e, 0x5b, 0xe4, 0xeb, 0xdf, 0x5b, 0x22, 0x49, 0x56, 0xa7, 0x98, 0xa4, 0xdf},
346                                         AssetID:             bc.AssetID{V0: 1},
347                                         Amount:              7,
348                                         AccountID:           "testAccount2",
349                                         Address:             "testAddress2",
350                                         ControlProgramIndex: 72,
351                                         Change:              false,
352                                 },
353                         },
354                 },
355         }
356
357         w := &Wallet{store: testStore}
358         for i, c := range cases {
359                 for s, p := range c.dbPrograms {
360                         data, err := json.Marshal(p)
361                         if err != nil {
362                                 t.Error(err)
363                         }
364                         key, err := hex.DecodeString(s)
365                         if err != nil {
366                                 t.Error(err)
367                         }
368                         testDB.Set(key, data)
369                 }
370
371                 fmt.Println("len(c.input):", len(c.input))
372                 gotUtxos := w.filterAccountUtxo(c.input)
373                 sort.Slice(gotUtxos[:], func(i, j int) bool {
374                         return gotUtxos[i].Amount < gotUtxos[j].Amount
375                 })
376
377                 if !testutil.DeepEqual(gotUtxos, c.wantUtxos) {
378                         t.Errorf("case %d: got %v want %v", i, gotUtxos, c.wantUtxos)
379                 }
380                 for s := range c.dbPrograms {
381                         key, err := hex.DecodeString(s)
382                         if err != nil {
383                                 t.Error(err)
384                         }
385                         testDB.Delete(key)
386                 }
387         }
388 }
389
390 func TestTxInToUtxos(t *testing.T) {
391         cases := []struct {
392                 tx         *types.Tx
393                 statusFail bool
394                 wantUtxos  []*account.UTXO
395         }{
396                 {
397                         tx: types.NewTx(types.TxData{
398                                 Inputs: []*types.TxInput{
399                                         types.NewCoinbaseInput([]byte{0x51}),
400                                 },
401                                 Outputs: []*types.TxOutput{
402                                         types.NewIntraChainOutput(*consensus.BTMAssetID, 41250000000, []byte{0x51}),
403                                 },
404                         }),
405                         statusFail: false,
406                         wantUtxos:  []*account.UTXO{},
407                 },
408                 {
409                         tx: types.NewTx(types.TxData{
410                                 Inputs: []*types.TxInput{
411                                         types.NewSpendInput([][]byte{}, bc.Hash{V0: 1}, bc.AssetID{V0: 1}, 1, 1, []byte{0x51}),
412                                         types.NewSpendInput([][]byte{}, bc.Hash{V0: 2}, bc.AssetID{V0: 1}, 3, 2, []byte{0x52}),
413                                         types.NewSpendInput([][]byte{}, bc.Hash{V0: 3}, *consensus.BTMAssetID, 5, 3, []byte{0x53}),
414                                         types.NewSpendInput([][]byte{}, bc.Hash{V0: 4}, *consensus.BTMAssetID, 7, 4, []byte{0x54}),
415                                 },
416                                 Outputs: []*types.TxOutput{
417                                         types.NewIntraChainOutput(bc.AssetID{V0: 1}, 4, []byte{0x51}),
418                                         types.NewIntraChainOutput(*consensus.BTMAssetID, 12, []byte{0x53}),
419                                 },
420                         }),
421                         statusFail: false,
422                         wantUtxos: []*account.UTXO{
423                                 &account.UTXO{
424                                         OutputID:       bc.NewHash([32]byte{0x62, 0xf2, 0xc4, 0xa0, 0x9b, 0x47, 0xd1, 0x53, 0x58, 0xe7, 0x8c, 0x49, 0x36, 0x75, 0x02, 0xc1, 0x63, 0x46, 0x51, 0xc4, 0x0f, 0xef, 0x63, 0xe2, 0x7d, 0xe4, 0x3c, 0xb3, 0x2c, 0xfe, 0x97, 0xa2}),
425                                         AssetID:        bc.AssetID{V0: 1},
426                                         Amount:         1,
427                                         ControlProgram: []byte{0x51},
428                                         SourceID:       bc.Hash{V0: 1},
429                                         SourcePos:      1,
430                                 },
431                                 &account.UTXO{
432                                         OutputID:       bc.NewHash([32]byte{0x99, 0x30, 0x35, 0x15, 0x9b, 0x0b, 0xcc, 0xdf, 0xbd, 0x15, 0x49, 0xb5, 0x2b, 0x4c, 0xc8, 0x71, 0x20, 0xe7, 0x2f, 0x77, 0x87, 0xcd, 0x88, 0x92, 0xba, 0xd8, 0x97, 0xfa, 0x4a, 0x2a, 0x1a, 0x10}),
433                                         AssetID:        bc.AssetID{V0: 1},
434                                         Amount:         3,
435                                         ControlProgram: []byte{0x52},
436                                         SourceID:       bc.Hash{V0: 2},
437                                         SourcePos:      2,
438                                 },
439                                 &account.UTXO{
440                                         OutputID:       bc.NewHash([32]byte{0xe5, 0x21, 0x0a, 0x9f, 0x17, 0xa2, 0x3a, 0xcf, 0x47, 0x57, 0xf2, 0x16, 0x12, 0x9d, 0xd8, 0xea, 0x7a, 0x9f, 0x5a, 0x14, 0xa8, 0xd6, 0x32, 0x6f, 0xe8, 0xa8, 0x8e, 0xb7, 0xf4, 0xb4, 0xfb, 0xbd}),
441                                         AssetID:        *consensus.BTMAssetID,
442                                         Amount:         5,
443                                         ControlProgram: []byte{0x53},
444                                         SourceID:       bc.Hash{V0: 3},
445                                         SourcePos:      3,
446                                 },
447                                 &account.UTXO{
448                                         OutputID:       bc.NewHash([32]byte{0x57, 0x65, 0x8d, 0x41, 0xed, 0xb7, 0x49, 0xd5, 0x1c, 0xf5, 0x95, 0x93, 0x16, 0x57, 0xf8, 0x66, 0x54, 0x1b, 0xb3, 0x45, 0x84, 0x19, 0x73, 0x2f, 0xb3, 0x3e, 0x44, 0x7c, 0x97, 0x33, 0x77, 0x12}),
449                                         AssetID:        *consensus.BTMAssetID,
450                                         Amount:         7,
451                                         ControlProgram: []byte{0x54},
452                                         SourceID:       bc.Hash{V0: 4},
453                                         SourcePos:      4,
454                                 },
455                         },
456                 },
457                 {
458                         tx: types.NewTx(types.TxData{
459                                 Inputs: []*types.TxInput{
460                                         types.NewSpendInput([][]byte{}, bc.Hash{V0: 1}, bc.AssetID{V0: 1}, 1, 1, []byte{0x51}),
461                                         types.NewSpendInput([][]byte{}, bc.Hash{V0: 2}, bc.AssetID{V0: 1}, 3, 2, []byte{0x52}),
462                                         types.NewSpendInput([][]byte{}, bc.Hash{V0: 3}, *consensus.BTMAssetID, 5, 3, []byte{0x53}),
463                                         types.NewSpendInput([][]byte{}, bc.Hash{V0: 4}, *consensus.BTMAssetID, 7, 4, []byte{0x54}),
464                                 },
465                                 Outputs: []*types.TxOutput{
466                                         types.NewIntraChainOutput(bc.AssetID{V0: 1}, 4, []byte{0x51}),
467                                         types.NewIntraChainOutput(*consensus.BTMAssetID, 12, []byte{0x53}),
468                                 },
469                         }),
470                         statusFail: true,
471                         wantUtxos: []*account.UTXO{
472                                 &account.UTXO{
473                                         OutputID:       bc.NewHash([32]byte{0xe5, 0x21, 0x0a, 0x9f, 0x17, 0xa2, 0x3a, 0xcf, 0x47, 0x57, 0xf2, 0x16, 0x12, 0x9d, 0xd8, 0xea, 0x7a, 0x9f, 0x5a, 0x14, 0xa8, 0xd6, 0x32, 0x6f, 0xe8, 0xa8, 0x8e, 0xb7, 0xf4, 0xb4, 0xfb, 0xbd}),
474                                         AssetID:        *consensus.BTMAssetID,
475                                         Amount:         5,
476                                         ControlProgram: []byte{0x53},
477                                         SourceID:       bc.Hash{V0: 3},
478                                         SourcePos:      3,
479                                 },
480                                 &account.UTXO{
481                                         OutputID:       bc.NewHash([32]byte{0x57, 0x65, 0x8d, 0x41, 0xed, 0xb7, 0x49, 0xd5, 0x1c, 0xf5, 0x95, 0x93, 0x16, 0x57, 0xf8, 0x66, 0x54, 0x1b, 0xb3, 0x45, 0x84, 0x19, 0x73, 0x2f, 0xb3, 0x3e, 0x44, 0x7c, 0x97, 0x33, 0x77, 0x12}),
482                                         AssetID:        *consensus.BTMAssetID,
483                                         Amount:         7,
484                                         ControlProgram: []byte{0x54},
485                                         SourceID:       bc.Hash{V0: 4},
486                                         SourcePos:      4,
487                                 },
488                         },
489                 },
490                 {
491                         tx: types.NewTx(types.TxData{
492                                 Inputs: []*types.TxInput{
493                                         types.NewVetoInput([][]byte{}, bc.Hash{V0: 1}, bc.AssetID{V0: 1}, 1, 1, []byte{0x51}, []byte("af594006a40837d9f028daabb6d589df0b9138daefad5683e5233c2646279217294a8d532e60863bcf196625a35fb8ceeffa3c09610eb92dcfb655a947f13269")),
494                                 },
495                                 Outputs: []*types.TxOutput{
496                                         types.NewIntraChainOutput(bc.AssetID{V0: 1}, 1, []byte{0x51}),
497                                 },
498                         }),
499                         statusFail: false,
500                         wantUtxos: []*account.UTXO{
501                                 &account.UTXO{
502                                         OutputID:       bc.NewHash([32]byte{0x7c, 0x75, 0x7f, 0x03, 0x67, 0x9b, 0xc2, 0x8f, 0x8f, 0xbd, 0x04, 0x25, 0x72, 0x42, 0x4b, 0x0b, 0x2a, 0xa4, 0x0e, 0x10, 0x0a, 0x6e, 0x99, 0x0e, 0x6d, 0x58, 0x92, 0x1d, 0xdd, 0xbe, 0xeb, 0x1a}),
503                                         AssetID:        bc.AssetID{V0: 1},
504                                         Amount:         1,
505                                         ControlProgram: []byte{0x51},
506                                         Vote:           []byte("af594006a40837d9f028daabb6d589df0b9138daefad5683e5233c2646279217294a8d532e60863bcf196625a35fb8ceeffa3c09610eb92dcfb655a947f13269"),
507                                         SourceID:       bc.Hash{V0: 1},
508                                         SourcePos:      1,
509                                 },
510                         },
511                 },
512         }
513
514         for i, c := range cases {
515                 if gotUtxos := txInToUtxos(c.tx, c.statusFail); !testutil.DeepEqual(gotUtxos, c.wantUtxos) {
516                         for k, v := range gotUtxos {
517                                 data, _ := json.Marshal(v)
518                                 fmt.Println(k, string(data))
519                         }
520                         for k, v := range c.wantUtxos {
521                                 data, _ := json.Marshal(v)
522                                 fmt.Println(k, string(data))
523                         }
524                         t.Errorf("case %d: got %v want %v", i, gotUtxos, c.wantUtxos)
525                 }
526         }
527 }
528
529 func TestTxOutToUtxos(t *testing.T) {
530         cases := []struct {
531                 tx          *types.Tx
532                 statusFail  bool
533                 blockHeight uint64
534                 wantUtxos   []*account.UTXO
535         }{
536                 {
537                         tx: types.NewTx(types.TxData{
538                                 Inputs: []*types.TxInput{
539                                         types.NewCoinbaseInput([]byte{0x51}),
540                                 },
541                                 Outputs: []*types.TxOutput{
542                                         types.NewIntraChainOutput(*consensus.BTMAssetID, 41250000000, []byte{0x51}),
543                                 },
544                         }),
545                         statusFail:  false,
546                         blockHeight: 98,
547                         wantUtxos: []*account.UTXO{
548                                 &account.UTXO{
549                                         OutputID:       bc.Hash{V0: 1728735075694344097, V1: 884766857607786922, V2: 12293210594955921685, V3: 11109045974561998790},
550                                         AssetID:        *consensus.BTMAssetID,
551                                         Amount:         41250000000,
552                                         ControlProgram: []byte{0x51},
553                                         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}),
554                                         SourcePos:      0,
555                                         ValidHeight:    198,
556                                 },
557                         },
558                 },
559                 {
560                         tx: types.NewTx(types.TxData{
561                                 Inputs: []*types.TxInput{
562                                         types.NewSpendInput([][]byte{}, bc.Hash{V0: 1}, bc.AssetID{V0: 1}, 5, 1, []byte{0x51}),
563                                         types.NewSpendInput([][]byte{}, bc.Hash{V0: 2}, *consensus.BTMAssetID, 7, 1, []byte{0x51}),
564                                 },
565                                 Outputs: []*types.TxOutput{
566                                         types.NewIntraChainOutput(bc.AssetID{V0: 1}, 2, []byte{0x51}),
567                                         types.NewIntraChainOutput(bc.AssetID{V0: 1}, 3, []byte{0x52}),
568                                         types.NewIntraChainOutput(*consensus.BTMAssetID, 2, []byte{0x53}),
569                                         types.NewIntraChainOutput(*consensus.BTMAssetID, 5, []byte{0x54}),
570                                 },
571                         }),
572                         statusFail:  false,
573                         blockHeight: 0,
574                         wantUtxos: []*account.UTXO{
575                                 &account.UTXO{
576                                         OutputID:       bc.Hash{V0: 8675398163687045889, V1: 7549510466747714094, V2: 13693077838209211470, V3: 6878568403630757599},
577                                         AssetID:        bc.AssetID{V0: 1},
578                                         Amount:         2,
579                                         ControlProgram: []byte{0x51},
580                                         SourceID:       bc.Hash{V0: 968805671293010031, V1: 9297014342000792994, V2: 16963674611624423333, V3: 2728293460397542670},
581                                         SourcePos:      0,
582                                 },
583                                 &account.UTXO{
584                                         OutputID:       bc.Hash{V0: 10393356437681643401, V1: 233963481123580514, V2: 17312171816916184445, V3: 16199332547392196559},
585                                         AssetID:        bc.AssetID{V0: 1},
586                                         Amount:         3,
587                                         ControlProgram: []byte{0x52},
588                                         SourceID:       bc.Hash{V0: 968805671293010031, V1: 9297014342000792994, V2: 16963674611624423333, V3: 2728293460397542670},
589                                         SourcePos:      1,
590                                 },
591                                 &account.UTXO{
592                                         OutputID:       bc.Hash{V0: 7067560744282869147, V1: 8991714784298240423, V2: 2595857933262917893, V3: 11490631006811252506},
593                                         AssetID:        *consensus.BTMAssetID,
594                                         Amount:         2,
595                                         ControlProgram: []byte{0x53},
596                                         SourceID:       bc.Hash{V0: 968805671293010031, V1: 9297014342000792994, V2: 16963674611624423333, V3: 2728293460397542670},
597                                         SourcePos:      2,
598                                 },
599                                 &account.UTXO{
600                                         OutputID:       bc.Hash{V0: 15425148469684856658, V1: 11568657474526458285, V2: 11930588814405533063, V3: 5058456773104068022},
601                                         AssetID:        *consensus.BTMAssetID,
602                                         Amount:         5,
603                                         ControlProgram: []byte{0x54},
604                                         SourceID:       bc.Hash{V0: 968805671293010031, V1: 9297014342000792994, V2: 16963674611624423333, V3: 2728293460397542670},
605                                         SourcePos:      3,
606                                 },
607                         },
608                 },
609                 {
610                         tx: types.NewTx(types.TxData{
611                                 Inputs: []*types.TxInput{
612                                         types.NewSpendInput([][]byte{}, bc.Hash{V0: 1}, bc.AssetID{V0: 1}, 5, 1, []byte{0x51}),
613                                         types.NewSpendInput([][]byte{}, bc.Hash{V0: 2}, *consensus.BTMAssetID, 7, 1, []byte{0x51}),
614                                 },
615                                 Outputs: []*types.TxOutput{
616                                         types.NewIntraChainOutput(bc.AssetID{V0: 1}, 2, []byte{0x51}),
617                                         types.NewIntraChainOutput(bc.AssetID{V0: 1}, 3, []byte{0x52}),
618                                         types.NewIntraChainOutput(*consensus.BTMAssetID, 2, []byte{0x53}),
619                                         types.NewIntraChainOutput(*consensus.BTMAssetID, 5, []byte{0x54}),
620                                 },
621                         }),
622                         statusFail:  true,
623                         blockHeight: 0,
624                         wantUtxos: []*account.UTXO{
625                                 &account.UTXO{
626                                         OutputID:       bc.Hash{V0: 7067560744282869147, V1: 8991714784298240423, V2: 2595857933262917893, V3: 11490631006811252506},
627                                         AssetID:        *consensus.BTMAssetID,
628                                         Amount:         2,
629                                         ControlProgram: []byte{0x53},
630                                         SourceID:       bc.Hash{V0: 968805671293010031, V1: 9297014342000792994, V2: 16963674611624423333, V3: 2728293460397542670},
631                                         SourcePos:      2,
632                                 },
633                                 &account.UTXO{
634                                         OutputID:       bc.Hash{V0: 15425148469684856658, V1: 11568657474526458285, V2: 11930588814405533063, V3: 5058456773104068022},
635                                         AssetID:        *consensus.BTMAssetID,
636                                         Amount:         5,
637                                         ControlProgram: []byte{0x54},
638                                         SourceID:       bc.Hash{V0: 968805671293010031, V1: 9297014342000792994, V2: 16963674611624423333, V3: 2728293460397542670},
639                                         SourcePos:      3,
640                                 },
641                         },
642                 },
643                 {
644                         tx: types.NewTx(types.TxData{
645                                 Inputs: []*types.TxInput{
646                                         types.NewSpendInput([][]byte{}, bc.Hash{V0: 1}, bc.AssetID{V0: 1}, 5, 1, []byte{0x51}),
647                                         types.NewSpendInput([][]byte{}, bc.Hash{V0: 2}, *consensus.BTMAssetID, 7, 1, []byte{0x51}),
648                                 },
649                                 Outputs: []*types.TxOutput{
650                                         types.NewIntraChainOutput(bc.AssetID{V0: 1}, 2, []byte{0x51}),
651                                         types.NewCrossChainOutput(bc.AssetID{V0: 1}, 3, []byte{0x52}),
652                                         types.NewIntraChainOutput(*consensus.BTMAssetID, 2, []byte{0x53}),
653                                         types.NewCrossChainOutput(*consensus.BTMAssetID, 5, []byte{0x54}),
654                                 },
655                         }),
656                         statusFail:  false,
657                         blockHeight: 0,
658                         wantUtxos: []*account.UTXO{
659                                 &account.UTXO{
660                                         OutputID:       bc.Hash{V0: 8675398163687045889, V1: 7549510466747714094, V2: 13693077838209211470, V3: 6878568403630757599},
661                                         AssetID:        bc.AssetID{V0: 1},
662                                         Amount:         2,
663                                         ControlProgram: []byte{0x51},
664                                         SourceID:       bc.Hash{V0: 968805671293010031, V1: 9297014342000792994, V2: 16963674611624423333, V3: 2728293460397542670},
665                                         SourcePos:      0,
666                                 },
667                                 &account.UTXO{
668                                         OutputID:       bc.Hash{V0: 7067560744282869147, V1: 8991714784298240423, V2: 2595857933262917893, V3: 11490631006811252506},
669                                         AssetID:        *consensus.BTMAssetID,
670                                         Amount:         2,
671                                         ControlProgram: []byte{0x53},
672                                         SourceID:       bc.Hash{V0: 968805671293010031, V1: 9297014342000792994, V2: 16963674611624423333, V3: 2728293460397542670},
673                                         SourcePos:      2,
674                                 },
675                         },
676                 },
677                 {
678                         tx: types.NewTx(types.TxData{
679                                 Inputs: []*types.TxInput{
680                                         types.NewCrossChainInput([][]byte{}, bc.Hash{V0: 1}, bc.AssetID{V0: 1}, 5, 1, 1, []byte("asset1"), []byte("IssuanceProgram")),
681                                         types.NewCrossChainInput([][]byte{}, bc.Hash{V0: 2}, *consensus.BTMAssetID, 7, 1, 1, []byte("assetbtm"), []byte("IssuanceProgram"))},
682                                 Outputs: []*types.TxOutput{
683                                         types.NewIntraChainOutput(bc.AssetID{V0: 1}, 2, []byte{0x51}),
684                                         types.NewIntraChainOutput(bc.AssetID{V0: 1}, 3, []byte{0x52}),
685                                         types.NewIntraChainOutput(*consensus.BTMAssetID, 2, []byte{0x53}),
686                                         types.NewIntraChainOutput(*consensus.BTMAssetID, 5, []byte{0x54}),
687                                 },
688                         }),
689                         statusFail:  false,
690                         blockHeight: 0,
691                         wantUtxos: []*account.UTXO{
692                                 &account.UTXO{
693                                         OutputID:       bc.Hash{V0: 5429526025956869574, V1: 12188959875155232503, V2: 14722092106507294798, V3: 27876074648890075},
694                                         AssetID:        bc.AssetID{V0: 1},
695                                         Amount:         2,
696                                         ControlProgram: []byte{0x51},
697                                         SourceID:       bc.Hash{V0: 10187915247323429348, V1: 4770401581694266753, V2: 4182269187154655368, V3: 9030883832705174512},
698                                         SourcePos:      0,
699                                 },
700                                 &account.UTXO{
701                                         OutputID:       bc.Hash{V0: 18100481287404207387, V1: 3365694797435565990, V2: 8136211093499423216, V3: 12028531817690438568},
702                                         AssetID:        bc.AssetID{V0: 1},
703                                         Amount:         3,
704                                         ControlProgram: []byte{0x52},
705                                         SourceID:       bc.Hash{V0: 10187915247323429348, V1: 4770401581694266753, V2: 4182269187154655368, V3: 9030883832705174512},
706                                         SourcePos:      1,
707                                 },
708                                 &account.UTXO{
709                                         OutputID:       bc.Hash{V0: 15745816911932387102, V1: 5035893487696724781, V2: 10084725527786878517, V3: 11270352747873435606},
710                                         AssetID:        *consensus.BTMAssetID,
711                                         Amount:         2,
712                                         ControlProgram: []byte{0x53},
713                                         SourceID:       bc.Hash{V0: 10187915247323429348, V1: 4770401581694266753, V2: 4182269187154655368, V3: 9030883832705174512},
714                                         SourcePos:      2,
715                                 },
716                                 &account.UTXO{
717                                         OutputID:       bc.Hash{V0: 10165799535720725897, V1: 9618876671942765420, V2: 17982649347111502590, V3: 15837286550437859084},
718                                         AssetID:        *consensus.BTMAssetID,
719                                         Amount:         5,
720                                         ControlProgram: []byte{0x54},
721                                         SourceID:       bc.Hash{V0: 10187915247323429348, V1: 4770401581694266753, V2: 4182269187154655368, V3: 9030883832705174512},
722                                         SourcePos:      3,
723                                 },
724                         },
725                 },
726         }
727
728         for i, c := range cases {
729                 if gotUtxos := txOutToUtxos(c.tx, c.statusFail, c.blockHeight); !testutil.DeepEqual(gotUtxos, c.wantUtxos) {
730                         t.Errorf("case %d: got %v want %v", i, gotUtxos, c.wantUtxos)
731
732                         for j, u := range gotUtxos {
733                                 t.Errorf("case %d: gotUtxos[%d] %v", i, j, u)
734                         }
735
736                         for j, u := range c.wantUtxos {
737                                 t.Errorf("case %d: c.wantUtxos[%d] %v", i, j, u)
738                         }
739                 }
740         }
741 }