OSDN Git Service

Modify the dependency on path
[bytom/vapor.git] / account / utxo_keeper_test.go
1 package account
2
3 import (
4         "encoding/json"
5         "os"
6         "testing"
7         "time"
8
9         dbm "github.com/tendermint/tmlibs/db"
10
11         "github.com/vapor/protocol/bc"
12         "github.com/vapor/testutil"
13 )
14
15 func TestAddUnconfirmedUtxo(t *testing.T) {
16         cases := []struct {
17                 before   utxoKeeper
18                 after    utxoKeeper
19                 addUtxos []*UTXO
20         }{
21                 {
22                         before: utxoKeeper{
23                                 unconfirmed: map[bc.Hash]*UTXO{},
24                         },
25                         after: utxoKeeper{
26                                 unconfirmed: map[bc.Hash]*UTXO{},
27                         },
28                         addUtxos: []*UTXO{},
29                 },
30                 {
31                         before: utxoKeeper{
32                                 unconfirmed: map[bc.Hash]*UTXO{},
33                         },
34                         after: utxoKeeper{
35                                 unconfirmed: map[bc.Hash]*UTXO{
36                                         bc.NewHash([32]byte{0x01}): &UTXO{OutputID: bc.NewHash([32]byte{0x01})},
37                                 },
38                         },
39                         addUtxos: []*UTXO{
40                                 &UTXO{OutputID: bc.NewHash([32]byte{0x01})},
41                         },
42                 },
43                 {
44                         before: utxoKeeper{
45                                 unconfirmed: map[bc.Hash]*UTXO{
46                                         bc.NewHash([32]byte{0x01}): &UTXO{OutputID: bc.NewHash([32]byte{0x01})},
47                                 },
48                         },
49                         after: utxoKeeper{
50                                 unconfirmed: map[bc.Hash]*UTXO{
51                                         bc.NewHash([32]byte{0x01}): &UTXO{OutputID: bc.NewHash([32]byte{0x01})},
52                                 },
53                         },
54                         addUtxos: []*UTXO{
55                                 &UTXO{OutputID: bc.NewHash([32]byte{0x01})},
56                         },
57                 },
58                 {
59                         before: utxoKeeper{
60                                 unconfirmed: map[bc.Hash]*UTXO{
61                                         bc.NewHash([32]byte{0x01}): &UTXO{OutputID: bc.NewHash([32]byte{0x01})},
62                                 },
63                         },
64                         after: utxoKeeper{
65                                 unconfirmed: map[bc.Hash]*UTXO{
66                                         bc.NewHash([32]byte{0x01}): &UTXO{OutputID: bc.NewHash([32]byte{0x01})},
67                                         bc.NewHash([32]byte{0x02}): &UTXO{OutputID: bc.NewHash([32]byte{0x02})},
68                                         bc.NewHash([32]byte{0x03}): &UTXO{OutputID: bc.NewHash([32]byte{0x03})},
69                                 },
70                         },
71                         addUtxos: []*UTXO{
72                                 &UTXO{OutputID: bc.NewHash([32]byte{0x02})},
73                                 &UTXO{OutputID: bc.NewHash([32]byte{0x03})},
74                         },
75                 },
76         }
77
78         for i, c := range cases {
79                 c.before.AddUnconfirmedUtxo(c.addUtxos)
80                 if !testutil.DeepEqual(c.before, c.after) {
81                         t.Errorf("case %d: got %v want %v", i, c.before, c.after)
82                 }
83         }
84 }
85
86 func TestCancel(t *testing.T) {
87         cases := []struct {
88                 before    utxoKeeper
89                 after     utxoKeeper
90                 cancelRid uint64
91         }{
92                 {
93                         before: utxoKeeper{
94                                 reserved:     map[bc.Hash]uint64{},
95                                 reservations: map[uint64]*reservation{},
96                         },
97                         after: utxoKeeper{
98                                 reserved:     map[bc.Hash]uint64{},
99                                 reservations: map[uint64]*reservation{},
100                         },
101                         cancelRid: 0,
102                 },
103                 {
104                         before: utxoKeeper{
105                                 reserved: map[bc.Hash]uint64{
106                                         bc.NewHash([32]byte{0x01}): 1,
107                                 },
108                                 reservations: map[uint64]*reservation{
109                                         1: &reservation{
110                                                 id: 1,
111                                                 utxos: []*UTXO{
112                                                         &UTXO{OutputID: bc.NewHash([32]byte{0x01})},
113                                                 },
114                                                 change: 9527,
115                                                 expiry: time.Date(2016, 8, 10, 0, 0, 0, 0, time.UTC),
116                                         },
117                                 },
118                         },
119                         after: utxoKeeper{
120                                 reserved:     map[bc.Hash]uint64{},
121                                 reservations: map[uint64]*reservation{},
122                         },
123                         cancelRid: 1,
124                 },
125                 {
126                         before: utxoKeeper{
127                                 reserved: map[bc.Hash]uint64{
128                                         bc.NewHash([32]byte{0x01}): 1,
129                                 },
130                                 reservations: map[uint64]*reservation{
131                                         1: &reservation{
132                                                 id: 1,
133                                                 utxos: []*UTXO{
134                                                         &UTXO{OutputID: bc.NewHash([32]byte{0x01})},
135                                                 },
136                                                 change: 9527,
137                                                 expiry: time.Date(2016, 8, 10, 0, 0, 0, 0, time.UTC),
138                                         },
139                                 },
140                         },
141                         after: utxoKeeper{
142                                 reserved: map[bc.Hash]uint64{
143                                         bc.NewHash([32]byte{0x01}): 1,
144                                 },
145                                 reservations: map[uint64]*reservation{
146                                         1: &reservation{
147                                                 id: 1,
148                                                 utxos: []*UTXO{
149                                                         &UTXO{OutputID: bc.NewHash([32]byte{0x01})},
150                                                 },
151                                                 change: 9527,
152                                                 expiry: time.Date(2016, 8, 10, 0, 0, 0, 0, time.UTC),
153                                         },
154                                 },
155                         },
156                         cancelRid: 2,
157                 },
158                 {
159                         before: utxoKeeper{
160                                 reserved: map[bc.Hash]uint64{
161                                         bc.NewHash([32]byte{0x01}): 1,
162                                         bc.NewHash([32]byte{0x02}): 3,
163                                         bc.NewHash([32]byte{0x03}): 3,
164                                         bc.NewHash([32]byte{0x04}): 3,
165                                 },
166                                 reservations: map[uint64]*reservation{
167                                         1: &reservation{
168                                                 id: 1,
169                                                 utxos: []*UTXO{
170                                                         &UTXO{OutputID: bc.NewHash([32]byte{0x01})},
171                                                 },
172                                                 change: 9527,
173                                                 expiry: time.Date(2016, 8, 10, 0, 0, 0, 0, time.UTC),
174                                         },
175                                         3: &reservation{
176                                                 id: 3,
177                                                 utxos: []*UTXO{
178                                                         &UTXO{OutputID: bc.NewHash([32]byte{0x02})},
179                                                         &UTXO{OutputID: bc.NewHash([32]byte{0x03})},
180                                                         &UTXO{OutputID: bc.NewHash([32]byte{0x04})},
181                                                 },
182                                                 change: 9528,
183                                                 expiry: time.Date(2016, 8, 10, 0, 0, 0, 0, time.UTC),
184                                         },
185                                 },
186                         },
187                         after: utxoKeeper{
188                                 reserved: map[bc.Hash]uint64{
189                                         bc.NewHash([32]byte{0x01}): 1,
190                                 },
191                                 reservations: map[uint64]*reservation{
192                                         1: &reservation{
193                                                 id: 1,
194                                                 utxos: []*UTXO{
195                                                         &UTXO{OutputID: bc.NewHash([32]byte{0x01})},
196                                                 },
197                                                 change: 9527,
198                                                 expiry: time.Date(2016, 8, 10, 0, 0, 0, 0, time.UTC),
199                                         },
200                                 },
201                         },
202                         cancelRid: 3,
203                 },
204         }
205
206         for i, c := range cases {
207                 c.before.cancel(c.cancelRid)
208                 if !testutil.DeepEqual(c.before, c.after) {
209                         t.Errorf("case %d: got %v want %v", i, c.before, c.after)
210                 }
211         }
212 }
213
214 func TestRemoveUnconfirmedUtxo(t *testing.T) {
215         cases := []struct {
216                 before      utxoKeeper
217                 after       utxoKeeper
218                 removeUtxos []*bc.Hash
219         }{
220                 {
221                         before: utxoKeeper{
222                                 unconfirmed: map[bc.Hash]*UTXO{},
223                         },
224                         after: utxoKeeper{
225                                 unconfirmed: map[bc.Hash]*UTXO{},
226                         },
227                         removeUtxos: []*bc.Hash{},
228                 },
229                 {
230                         before: utxoKeeper{
231                                 unconfirmed: map[bc.Hash]*UTXO{
232                                         bc.Hash{V0: 1}: &UTXO{OutputID: bc.NewHash([32]byte{0x01})},
233                                 },
234                         },
235                         after: utxoKeeper{
236                                 unconfirmed: map[bc.Hash]*UTXO{},
237                         },
238                         removeUtxos: []*bc.Hash{
239                                 &bc.Hash{V0: 1},
240                         },
241                 },
242                 {
243                         before: utxoKeeper{
244                                 unconfirmed: map[bc.Hash]*UTXO{
245                                         bc.Hash{V0: 1}: &UTXO{OutputID: bc.NewHash([32]byte{0x01})},
246                                         bc.Hash{V0: 2}: &UTXO{OutputID: bc.NewHash([32]byte{0x02})},
247                                         bc.Hash{V0: 3}: &UTXO{OutputID: bc.NewHash([32]byte{0x03})},
248                                         bc.Hash{V0: 4}: &UTXO{OutputID: bc.NewHash([32]byte{0x04})},
249                                         bc.Hash{V0: 5}: &UTXO{OutputID: bc.NewHash([32]byte{0x05})},
250                                 },
251                         },
252                         after: utxoKeeper{
253                                 unconfirmed: map[bc.Hash]*UTXO{
254                                         bc.Hash{V0: 2}: &UTXO{OutputID: bc.NewHash([32]byte{0x02})},
255                                         bc.Hash{V0: 4}: &UTXO{OutputID: bc.NewHash([32]byte{0x04})},
256                                 },
257                         },
258                         removeUtxos: []*bc.Hash{
259                                 &bc.Hash{V0: 1},
260                                 &bc.Hash{V0: 3},
261                                 &bc.Hash{V0: 5},
262                         },
263                 },
264         }
265
266         for i, c := range cases {
267                 c.before.RemoveUnconfirmedUtxo(c.removeUtxos)
268                 if !testutil.DeepEqual(c.before, c.after) {
269                         t.Errorf("case %d: got %v want %v", i, c.before, c.after)
270                 }
271         }
272 }
273
274 func TestReserve(t *testing.T) {
275         currentHeight := func() uint64 { return 9527 }
276         testDB := dbm.NewDB("testdb", "leveldb", "temp")
277         defer os.RemoveAll("temp")
278
279         cases := []struct {
280                 before        utxoKeeper
281                 after         utxoKeeper
282                 err           error
283                 reserveAmount uint64
284                 exp           time.Time
285         }{
286                 {
287                         before: utxoKeeper{
288                                 db:            testDB,
289                                 currentHeight: currentHeight,
290                                 reserved:      map[bc.Hash]uint64{},
291                                 reservations:  map[uint64]*reservation{},
292                         },
293                         after: utxoKeeper{
294                                 db:            testDB,
295                                 currentHeight: currentHeight,
296                                 reserved:      map[bc.Hash]uint64{},
297                                 reservations:  map[uint64]*reservation{},
298                         },
299                         reserveAmount: 1,
300                         err:           ErrInsufficient,
301                 },
302                 {
303                         before: utxoKeeper{
304                                 db:            testDB,
305                                 currentHeight: currentHeight,
306                                 unconfirmed: map[bc.Hash]*UTXO{
307                                         bc.NewHash([32]byte{0x01}): &UTXO{
308                                                 OutputID:  bc.NewHash([32]byte{0x01}),
309                                                 AccountID: "testAccount",
310                                                 Amount:    3,
311                                         },
312                                 },
313                                 reserved:     map[bc.Hash]uint64{},
314                                 reservations: map[uint64]*reservation{},
315                         },
316                         after: utxoKeeper{
317                                 db:            testDB,
318                                 currentHeight: currentHeight,
319                                 unconfirmed: map[bc.Hash]*UTXO{
320                                         bc.NewHash([32]byte{0x01}): &UTXO{
321                                                 OutputID:  bc.NewHash([32]byte{0x01}),
322                                                 AccountID: "testAccount",
323                                                 Amount:    3,
324                                         },
325                                 },
326                                 reserved:     map[bc.Hash]uint64{},
327                                 reservations: map[uint64]*reservation{},
328                         },
329                         reserveAmount: 4,
330                         err:           ErrInsufficient,
331                 },
332                 {
333                         before: utxoKeeper{
334                                 db:            testDB,
335                                 currentHeight: currentHeight,
336                                 unconfirmed: map[bc.Hash]*UTXO{
337                                         bc.NewHash([32]byte{0x01}): &UTXO{
338                                                 OutputID:    bc.NewHash([32]byte{0x01}),
339                                                 AccountID:   "testAccount",
340                                                 Amount:      3,
341                                                 ValidHeight: 9528,
342                                         },
343                                 },
344                                 reserved:     map[bc.Hash]uint64{},
345                                 reservations: map[uint64]*reservation{},
346                         },
347                         after: utxoKeeper{
348                                 db:            testDB,
349                                 currentHeight: currentHeight,
350                                 unconfirmed: map[bc.Hash]*UTXO{
351                                         bc.NewHash([32]byte{0x01}): &UTXO{
352                                                 OutputID:    bc.NewHash([32]byte{0x01}),
353                                                 AccountID:   "testAccount",
354                                                 Amount:      3,
355                                                 ValidHeight: 9528,
356                                         },
357                                 },
358                                 reserved:     map[bc.Hash]uint64{},
359                                 reservations: map[uint64]*reservation{},
360                         },
361                         reserveAmount: 3,
362                         err:           ErrImmature,
363                 },
364                 {
365                         before: utxoKeeper{
366                                 db:            testDB,
367                                 currentHeight: currentHeight,
368                                 unconfirmed: map[bc.Hash]*UTXO{
369                                         bc.NewHash([32]byte{0x01}): &UTXO{
370                                                 OutputID:  bc.NewHash([32]byte{0x01}),
371                                                 AccountID: "testAccount",
372                                                 Amount:    3,
373                                         },
374                                 },
375                                 reserved: map[bc.Hash]uint64{
376                                         bc.NewHash([32]byte{0x01}): 0,
377                                 },
378                                 reservations: map[uint64]*reservation{},
379                         },
380                         after: utxoKeeper{
381                                 db:            testDB,
382                                 currentHeight: currentHeight,
383                                 unconfirmed: map[bc.Hash]*UTXO{
384                                         bc.NewHash([32]byte{0x01}): &UTXO{
385                                                 OutputID:  bc.NewHash([32]byte{0x01}),
386                                                 AccountID: "testAccount",
387                                                 Amount:    3,
388                                         },
389                                 },
390                                 reserved: map[bc.Hash]uint64{
391                                         bc.NewHash([32]byte{0x01}): 0,
392                                 },
393                                 reservations: map[uint64]*reservation{},
394                         },
395                         reserveAmount: 3,
396                         err:           ErrReserved,
397                 },
398                 {
399                         before: utxoKeeper{
400                                 db:            testDB,
401                                 currentHeight: currentHeight,
402                                 unconfirmed: map[bc.Hash]*UTXO{
403                                         bc.NewHash([32]byte{0x01}): &UTXO{
404                                                 OutputID:  bc.NewHash([32]byte{0x01}),
405                                                 AccountID: "testAccount",
406                                                 Amount:    3,
407                                         },
408                                 },
409                                 reserved:     map[bc.Hash]uint64{},
410                                 reservations: map[uint64]*reservation{},
411                         },
412                         after: utxoKeeper{
413                                 db:            testDB,
414                                 currentHeight: currentHeight,
415                                 unconfirmed: map[bc.Hash]*UTXO{
416                                         bc.NewHash([32]byte{0x01}): &UTXO{
417                                                 OutputID:  bc.NewHash([32]byte{0x01}),
418                                                 AccountID: "testAccount",
419                                                 Amount:    3,
420                                         },
421                                 },
422                                 reserved: map[bc.Hash]uint64{
423                                         bc.NewHash([32]byte{0x01}): 1,
424                                 },
425                                 reservations: map[uint64]*reservation{
426                                         1: &reservation{
427                                                 id: 1,
428                                                 utxos: []*UTXO{
429                                                         &UTXO{
430                                                                 OutputID:  bc.NewHash([32]byte{0x01}),
431                                                                 AccountID: "testAccount",
432                                                                 Amount:    3,
433                                                         },
434                                                 },
435                                                 change: 1,
436                                                 expiry: time.Date(2016, 8, 10, 0, 0, 0, 0, time.UTC),
437                                         },
438                                 },
439                         },
440                         reserveAmount: 2,
441                         err:           nil,
442                         exp:           time.Date(2016, 8, 10, 0, 0, 0, 0, time.UTC),
443                 },
444                 {
445                         before: utxoKeeper{
446                                 db:            testDB,
447                                 currentHeight: currentHeight,
448                                 nextIndex:     1,
449                                 unconfirmed: map[bc.Hash]*UTXO{
450                                         bc.NewHash([32]byte{0x01}): &UTXO{
451                                                 OutputID:  bc.NewHash([32]byte{0x01}),
452                                                 AccountID: "testAccount",
453                                                 Amount:    3,
454                                         },
455                                         bc.NewHash([32]byte{0x02}): &UTXO{
456                                                 OutputID:  bc.NewHash([32]byte{0x02}),
457                                                 AccountID: "testAccount",
458                                                 Amount:    5,
459                                         },
460                                         bc.NewHash([32]byte{0x03}): &UTXO{
461                                                 OutputID:  bc.NewHash([32]byte{0x03}),
462                                                 AccountID: "testAccount",
463                                                 Amount:    7,
464                                         },
465                                 },
466                                 reserved: map[bc.Hash]uint64{
467                                         bc.NewHash([32]byte{0x01}): 1,
468                                 },
469                                 reservations: map[uint64]*reservation{},
470                         },
471                         after: utxoKeeper{
472                                 db:            testDB,
473                                 currentHeight: currentHeight,
474                                 unconfirmed: map[bc.Hash]*UTXO{
475                                         bc.NewHash([32]byte{0x01}): &UTXO{
476                                                 OutputID:  bc.NewHash([32]byte{0x01}),
477                                                 AccountID: "testAccount",
478                                                 Amount:    3,
479                                         },
480                                         bc.NewHash([32]byte{0x02}): &UTXO{
481                                                 OutputID:  bc.NewHash([32]byte{0x02}),
482                                                 AccountID: "testAccount",
483                                                 Amount:    5,
484                                         },
485                                         bc.NewHash([32]byte{0x03}): &UTXO{
486                                                 OutputID:  bc.NewHash([32]byte{0x03}),
487                                                 AccountID: "testAccount",
488                                                 Amount:    7,
489                                         },
490                                 },
491                                 reserved: map[bc.Hash]uint64{
492                                         bc.NewHash([32]byte{0x01}): 1,
493                                         bc.NewHash([32]byte{0x02}): 2,
494                                         bc.NewHash([32]byte{0x03}): 2,
495                                 },
496                                 reservations: map[uint64]*reservation{
497                                         2: &reservation{
498                                                 id: 2,
499                                                 utxos: []*UTXO{
500                                                         &UTXO{
501                                                                 OutputID:  bc.NewHash([32]byte{0x03}),
502                                                                 AccountID: "testAccount",
503                                                                 Amount:    7,
504                                                         },
505                                                         &UTXO{
506                                                                 OutputID:  bc.NewHash([32]byte{0x02}),
507                                                                 AccountID: "testAccount",
508                                                                 Amount:    5,
509                                                         },
510                                                 },
511                                                 change: 4,
512                                                 expiry: time.Date(2016, 8, 10, 0, 0, 0, 0, time.UTC),
513                                         },
514                                 },
515                         },
516                         reserveAmount: 8,
517                         err:           nil,
518                         exp:           time.Date(2016, 8, 10, 0, 0, 0, 0, time.UTC),
519                 },
520         }
521
522         for i, c := range cases {
523                 if _, err := c.before.Reserve("testAccount", &bc.AssetID{}, c.reserveAmount, true, c.exp); err != c.err {
524                         t.Errorf("case %d: got error %v want error %v", i, err, c.err)
525                 }
526                 checkUtxoKeeperEqual(t, i, &c.before, &c.after)
527         }
528 }
529
530 func TestReserveParticular(t *testing.T) {
531         currentHeight := func() uint64 { return 9527 }
532         testDB := dbm.NewDB("testdb", "leveldb", "temp")
533         defer os.RemoveAll("temp")
534
535         cases := []struct {
536                 before      utxoKeeper
537                 after       utxoKeeper
538                 err         error
539                 reserveHash bc.Hash
540                 exp         time.Time
541         }{
542                 {
543                         before: utxoKeeper{
544                                 db:            testDB,
545                                 currentHeight: currentHeight,
546                                 unconfirmed: map[bc.Hash]*UTXO{
547                                         bc.NewHash([32]byte{0x01}): &UTXO{
548                                                 OutputID:  bc.NewHash([32]byte{0x01}),
549                                                 AccountID: "testAccount",
550                                                 Amount:    3,
551                                         },
552                                 },
553                                 reserved: map[bc.Hash]uint64{
554                                         bc.NewHash([32]byte{0x01}): 0,
555                                 },
556                                 reservations: map[uint64]*reservation{},
557                         },
558                         after: utxoKeeper{
559                                 db:            testDB,
560                                 currentHeight: currentHeight,
561                                 unconfirmed: map[bc.Hash]*UTXO{
562                                         bc.NewHash([32]byte{0x01}): &UTXO{
563                                                 OutputID:  bc.NewHash([32]byte{0x01}),
564                                                 AccountID: "testAccount",
565                                                 Amount:    3,
566                                         },
567                                 },
568                                 reserved: map[bc.Hash]uint64{
569                                         bc.NewHash([32]byte{0x01}): 0,
570                                 },
571                                 reservations: map[uint64]*reservation{},
572                         },
573                         reserveHash: bc.NewHash([32]byte{0x01}),
574                         err:         ErrReserved,
575                 },
576                 {
577                         before: utxoKeeper{
578                                 db:            testDB,
579                                 currentHeight: currentHeight,
580                                 unconfirmed: map[bc.Hash]*UTXO{
581                                         bc.NewHash([32]byte{0x01}): &UTXO{
582                                                 OutputID:    bc.NewHash([32]byte{0x01}),
583                                                 AccountID:   "testAccount",
584                                                 Amount:      3,
585                                                 ValidHeight: 9528,
586                                         },
587                                 },
588                                 reserved:     map[bc.Hash]uint64{},
589                                 reservations: map[uint64]*reservation{},
590                         },
591                         after: utxoKeeper{
592                                 db:            testDB,
593                                 currentHeight: currentHeight,
594                                 unconfirmed: map[bc.Hash]*UTXO{
595                                         bc.NewHash([32]byte{0x01}): &UTXO{
596                                                 OutputID:    bc.NewHash([32]byte{0x01}),
597                                                 AccountID:   "testAccount",
598                                                 Amount:      3,
599                                                 ValidHeight: 9528,
600                                         },
601                                 },
602                                 reserved:     map[bc.Hash]uint64{},
603                                 reservations: map[uint64]*reservation{},
604                         },
605                         reserveHash: bc.NewHash([32]byte{0x01}),
606                         err:         ErrImmature,
607                 },
608                 {
609                         before: utxoKeeper{
610                                 db:            testDB,
611                                 currentHeight: currentHeight,
612                                 unconfirmed: map[bc.Hash]*UTXO{
613                                         bc.NewHash([32]byte{0x01}): &UTXO{
614                                                 OutputID:  bc.NewHash([32]byte{0x01}),
615                                                 AccountID: "testAccount",
616                                                 Amount:    3,
617                                         },
618                                 },
619                                 reserved:     map[bc.Hash]uint64{},
620                                 reservations: map[uint64]*reservation{},
621                         },
622                         after: utxoKeeper{
623                                 db:            testDB,
624                                 currentHeight: currentHeight,
625                                 unconfirmed: map[bc.Hash]*UTXO{
626                                         bc.NewHash([32]byte{0x01}): &UTXO{
627                                                 OutputID:  bc.NewHash([32]byte{0x01}),
628                                                 AccountID: "testAccount",
629                                                 Amount:    3,
630                                         },
631                                 },
632                                 reserved: map[bc.Hash]uint64{
633                                         bc.NewHash([32]byte{0x01}): 1,
634                                 },
635                                 reservations: map[uint64]*reservation{
636                                         1: &reservation{
637                                                 id: 1,
638                                                 utxos: []*UTXO{
639                                                         &UTXO{
640                                                                 OutputID:  bc.NewHash([32]byte{0x01}),
641                                                                 AccountID: "testAccount",
642                                                                 Amount:    3,
643                                                         },
644                                                 },
645                                                 change: 0,
646                                                 expiry: time.Date(2016, 8, 10, 0, 0, 0, 0, time.UTC),
647                                         },
648                                 },
649                         },
650                         reserveHash: bc.NewHash([32]byte{0x01}),
651                         err:         nil,
652                         exp:         time.Date(2016, 8, 10, 0, 0, 0, 0, time.UTC),
653                 },
654         }
655
656         for i, c := range cases {
657                 if _, err := c.before.ReserveParticular(c.reserveHash, true, c.exp); err != c.err {
658                         t.Errorf("case %d: got error %v want error %v", i, err, c.err)
659                 }
660                 checkUtxoKeeperEqual(t, i, &c.before, &c.after)
661         }
662 }
663
664 func TestExpireReservation(t *testing.T) {
665         before := &utxoKeeper{
666                 reservations: map[uint64]*reservation{
667                         1: &reservation{expiry: time.Date(2016, 8, 10, 0, 0, 0, 0, time.UTC)},
668                         2: &reservation{expiry: time.Date(3016, 8, 10, 0, 0, 0, 0, time.UTC)},
669                         3: &reservation{expiry: time.Date(2016, 8, 10, 0, 0, 0, 0, time.UTC)},
670                         4: &reservation{expiry: time.Date(3016, 8, 10, 0, 0, 0, 0, time.UTC)},
671                         5: &reservation{expiry: time.Date(3016, 8, 10, 0, 0, 0, 0, time.UTC)},
672                 },
673         }
674         after := &utxoKeeper{
675                 reservations: map[uint64]*reservation{
676                         2: &reservation{expiry: time.Date(3016, 8, 10, 0, 0, 0, 0, time.UTC)},
677                         4: &reservation{expiry: time.Date(3016, 8, 10, 0, 0, 0, 0, time.UTC)},
678                         5: &reservation{expiry: time.Date(3016, 8, 10, 0, 0, 0, 0, time.UTC)},
679                 },
680         }
681         before.expireReservation(time.Date(2017, 8, 10, 0, 0, 0, 0, time.UTC))
682         checkUtxoKeeperEqual(t, 0, before, after)
683 }
684
685 func TestFindUtxos(t *testing.T) {
686         currentHeight := func() uint64 { return 9527 }
687         testDB := dbm.NewDB("testdb", "leveldb", "temp")
688         defer os.RemoveAll("temp")
689
690         cases := []struct {
691                 uk             utxoKeeper
692                 dbUtxos        []*UTXO
693                 useUnconfirmed bool
694                 wantUtxos      []*UTXO
695                 immatureAmount uint64
696         }{
697                 {
698                         uk: utxoKeeper{
699                                 db:            testDB,
700                                 currentHeight: currentHeight,
701                                 unconfirmed:   map[bc.Hash]*UTXO{},
702                         },
703                         dbUtxos:        []*UTXO{},
704                         useUnconfirmed: true,
705                         wantUtxos:      []*UTXO{},
706                         immatureAmount: 0,
707                 },
708                 {
709                         uk: utxoKeeper{
710                                 db:            testDB,
711                                 currentHeight: currentHeight,
712                                 unconfirmed:   map[bc.Hash]*UTXO{},
713                         },
714                         dbUtxos: []*UTXO{
715                                 &UTXO{
716                                         OutputID:  bc.NewHash([32]byte{0x01}),
717                                         AccountID: "testAccount",
718                                         Amount:    3,
719                                 },
720                                 &UTXO{
721                                         OutputID:  bc.NewHash([32]byte{0x02}),
722                                         AccountID: "testAccount",
723                                         AssetID:   bc.AssetID{V0: 6},
724                                         Amount:    3,
725                                 },
726                         },
727                         useUnconfirmed: false,
728                         wantUtxos: []*UTXO{
729                                 &UTXO{
730                                         OutputID:  bc.NewHash([32]byte{0x01}),
731                                         AccountID: "testAccount",
732                                         Amount:    3,
733                                 },
734                         },
735                         immatureAmount: 0,
736                 },
737                 {
738                         uk: utxoKeeper{
739                                 db:            testDB,
740                                 currentHeight: currentHeight,
741                                 unconfirmed:   map[bc.Hash]*UTXO{},
742                         },
743                         dbUtxos: []*UTXO{
744                                 &UTXO{
745                                         OutputID:    bc.NewHash([32]byte{0x02}),
746                                         AccountID:   "testAccount",
747                                         Amount:      3,
748                                         ValidHeight: 9528,
749                                 },
750                         },
751                         useUnconfirmed: false,
752                         wantUtxos:      []*UTXO{},
753                         immatureAmount: 3,
754                 },
755                 {
756                         uk: utxoKeeper{
757                                 db:            testDB,
758                                 currentHeight: currentHeight,
759                                 unconfirmed: map[bc.Hash]*UTXO{
760                                         bc.NewHash([32]byte{0x01}): &UTXO{
761                                                 OutputID:  bc.NewHash([32]byte{0x01}),
762                                                 AccountID: "testAccount",
763                                                 Amount:    3,
764                                         },
765                                 },
766                         },
767                         dbUtxos: []*UTXO{
768                                 &UTXO{
769                                         OutputID:  bc.NewHash([32]byte{0x02}),
770                                         AccountID: "testAccount",
771                                         Amount:    3,
772                                 },
773                         },
774                         useUnconfirmed: false,
775                         wantUtxos: []*UTXO{
776                                 &UTXO{
777                                         OutputID:  bc.NewHash([32]byte{0x02}),
778                                         AccountID: "testAccount",
779                                         Amount:    3,
780                                 },
781                         },
782                         immatureAmount: 0,
783                 },
784                 {
785                         uk: utxoKeeper{
786                                 db:            testDB,
787                                 currentHeight: currentHeight,
788                                 unconfirmed: map[bc.Hash]*UTXO{
789                                         bc.NewHash([32]byte{0x11}): &UTXO{
790                                                 OutputID:  bc.NewHash([32]byte{0x01}),
791                                                 AccountID: "testAccount",
792                                                 Amount:    3,
793                                         },
794                                 },
795                         },
796                         dbUtxos: []*UTXO{
797                                 &UTXO{
798                                         OutputID:  bc.NewHash([32]byte{0x02}),
799                                         AccountID: "testAccount",
800                                         Amount:    3,
801                                 },
802                         },
803                         useUnconfirmed: true,
804                         wantUtxos: []*UTXO{
805                                 &UTXO{
806                                         OutputID:  bc.NewHash([32]byte{0x02}),
807                                         AccountID: "testAccount",
808                                         Amount:    3,
809                                 },
810                                 &UTXO{
811                                         OutputID:  bc.NewHash([32]byte{0x01}),
812                                         AccountID: "testAccount",
813                                         Amount:    3,
814                                 },
815                         },
816                         immatureAmount: 0,
817                 },
818                 {
819                         uk: utxoKeeper{
820                                 db:            testDB,
821                                 currentHeight: currentHeight,
822                                 unconfirmed: map[bc.Hash]*UTXO{
823                                         bc.NewHash([32]byte{0x01}): &UTXO{
824                                                 OutputID:  bc.NewHash([32]byte{0x01}),
825                                                 AccountID: "testAccount",
826                                                 Amount:    1,
827                                         },
828                                         bc.NewHash([32]byte{0x02}): &UTXO{
829                                                 OutputID:  bc.NewHash([32]byte{0x02}),
830                                                 AccountID: "notMe",
831                                                 Amount:    2,
832                                         },
833                                 },
834                         },
835                         dbUtxos: []*UTXO{
836                                 &UTXO{
837                                         OutputID:  bc.NewHash([32]byte{0x03}),
838                                         AccountID: "testAccount",
839                                         Amount:    3,
840                                 },
841                                 &UTXO{
842                                         OutputID:  bc.NewHash([32]byte{0x04}),
843                                         AccountID: "notMe",
844                                         Amount:    4,
845                                 },
846                         },
847                         useUnconfirmed: true,
848                         wantUtxos: []*UTXO{
849                                 &UTXO{
850                                         OutputID:  bc.NewHash([32]byte{0x03}),
851                                         AccountID: "testAccount",
852                                         Amount:    3,
853                                 },
854                                 &UTXO{
855                                         OutputID:  bc.NewHash([32]byte{0x01}),
856                                         AccountID: "testAccount",
857                                         Amount:    1,
858                                 },
859                         },
860                         immatureAmount: 0,
861                 },
862         }
863
864         for i, c := range cases {
865                 for _, u := range c.dbUtxos {
866                         data, err := json.Marshal(u)
867                         if err != nil {
868                                 t.Error(err)
869                         }
870                         testDB.Set(StandardUTXOKey(u.OutputID), data)
871                 }
872
873                 gotUtxos, immatureAmount := c.uk.findUtxos("testAccount", &bc.AssetID{}, c.useUnconfirmed)
874                 if !testutil.DeepEqual(gotUtxos, c.wantUtxos) {
875                         t.Errorf("case %d: got %v want %v", i, gotUtxos, c.wantUtxos)
876                 }
877                 if immatureAmount != c.immatureAmount {
878                         t.Errorf("case %d: got %v want %v", i, immatureAmount, c.immatureAmount)
879                 }
880
881                 for _, u := range c.dbUtxos {
882                         testDB.Delete(StandardUTXOKey(u.OutputID))
883                 }
884         }
885 }
886
887 func TestFindUtxo(t *testing.T) {
888         currentHeight := func() uint64 { return 9527 }
889         testDB := dbm.NewDB("testdb", "leveldb", "temp")
890         defer os.RemoveAll("temp")
891
892         cases := []struct {
893                 uk             utxoKeeper
894                 dbUtxos        map[string]*UTXO
895                 outHash        bc.Hash
896                 useUnconfirmed bool
897                 wantUtxo       *UTXO
898                 err            error
899         }{
900                 {
901                         uk: utxoKeeper{
902                                 db:            testDB,
903                                 currentHeight: currentHeight,
904                                 unconfirmed:   map[bc.Hash]*UTXO{},
905                         },
906                         dbUtxos:  map[string]*UTXO{},
907                         outHash:  bc.NewHash([32]byte{0x01}),
908                         wantUtxo: nil,
909                         err:      ErrMatchUTXO,
910                 },
911                 {
912                         uk: utxoKeeper{
913                                 db:            testDB,
914                                 currentHeight: currentHeight,
915                                 unconfirmed: map[bc.Hash]*UTXO{
916                                         bc.NewHash([32]byte{0x01}): &UTXO{OutputID: bc.NewHash([32]byte{0x01})},
917                                 },
918                         },
919                         dbUtxos:        map[string]*UTXO{},
920                         outHash:        bc.NewHash([32]byte{0x01}),
921                         wantUtxo:       nil,
922                         useUnconfirmed: false,
923                         err:            ErrMatchUTXO,
924                 },
925                 {
926                         uk: utxoKeeper{
927                                 db:            testDB,
928                                 currentHeight: currentHeight,
929                                 unconfirmed: map[bc.Hash]*UTXO{
930                                         bc.NewHash([32]byte{0x01}): &UTXO{OutputID: bc.NewHash([32]byte{0x01})},
931                                 },
932                         },
933                         dbUtxos:        map[string]*UTXO{},
934                         outHash:        bc.NewHash([32]byte{0x01}),
935                         wantUtxo:       &UTXO{OutputID: bc.NewHash([32]byte{0x01})},
936                         useUnconfirmed: true,
937                         err:            nil,
938                 },
939                 {
940                         uk: utxoKeeper{
941                                 db:            testDB,
942                                 currentHeight: currentHeight,
943                                 unconfirmed:   map[bc.Hash]*UTXO{},
944                         },
945                         dbUtxos: map[string]*UTXO{
946                                 string(StandardUTXOKey(bc.NewHash([32]byte{0x01}))): &UTXO{OutputID: bc.NewHash([32]byte{0x01})},
947                         },
948                         outHash:        bc.NewHash([32]byte{0x01}),
949                         wantUtxo:       &UTXO{OutputID: bc.NewHash([32]byte{0x01})},
950                         useUnconfirmed: false,
951                         err:            nil,
952                 },
953                 {
954                         uk: utxoKeeper{
955                                 db:            testDB,
956                                 currentHeight: currentHeight,
957                                 unconfirmed:   map[bc.Hash]*UTXO{},
958                         },
959                         dbUtxos: map[string]*UTXO{
960                                 string(ContractUTXOKey(bc.NewHash([32]byte{0x01}))): &UTXO{OutputID: bc.NewHash([32]byte{0x01})},
961                         },
962                         outHash:        bc.NewHash([32]byte{0x01}),
963                         wantUtxo:       &UTXO{OutputID: bc.NewHash([32]byte{0x01})},
964                         useUnconfirmed: false,
965                         err:            nil,
966                 },
967         }
968
969         for i, c := range cases {
970                 for k, u := range c.dbUtxos {
971                         data, err := json.Marshal(u)
972                         if err != nil {
973                                 t.Error(err)
974                         }
975                         testDB.Set([]byte(k), data)
976                 }
977
978                 gotUtxo, err := c.uk.findUtxo(c.outHash, c.useUnconfirmed)
979                 if !testutil.DeepEqual(gotUtxo, c.wantUtxo) {
980                         t.Errorf("case %d: got %v want %v", i, gotUtxo, c.wantUtxo)
981                 }
982                 if err != c.err {
983                         t.Errorf("case %d: got %v want %v", i, err, c.err)
984                 }
985
986                 for _, u := range c.dbUtxos {
987                         testDB.Delete(StandardUTXOKey(u.OutputID))
988                 }
989         }
990 }
991
992 func TestOptUTXOs(t *testing.T) {
993         cases := []struct {
994                 uk             utxoKeeper
995                 input          []*UTXO
996                 inputAmount    uint64
997                 wantUtxos      []*UTXO
998                 optAmount      uint64
999                 reservedAmount uint64
1000         }{
1001                 {
1002                         uk: utxoKeeper{
1003                                 reserved: map[bc.Hash]uint64{
1004                                         bc.NewHash([32]byte{0x01}): 1,
1005                                 },
1006                         },
1007                         input:          []*UTXO{},
1008                         inputAmount:    13,
1009                         wantUtxos:      []*UTXO{},
1010                         optAmount:      0,
1011                         reservedAmount: 0,
1012                 },
1013                 {
1014                         uk: utxoKeeper{
1015                                 reserved: map[bc.Hash]uint64{
1016                                         bc.NewHash([32]byte{0x01}): 1,
1017                                 },
1018                         },
1019                         input: []*UTXO{
1020                                 &UTXO{OutputID: bc.NewHash([32]byte{0x01}), Amount: 1},
1021                         },
1022                         inputAmount:    13,
1023                         wantUtxos:      []*UTXO{},
1024                         optAmount:      0,
1025                         reservedAmount: 1,
1026                 },
1027                 {
1028                         uk: utxoKeeper{
1029                                 reserved: map[bc.Hash]uint64{
1030                                         bc.NewHash([32]byte{0x01}): 1,
1031                                 },
1032                         },
1033                         input: []*UTXO{
1034                                 &UTXO{OutputID: bc.NewHash([32]byte{0x01}), Amount: 1},
1035                                 &UTXO{OutputID: bc.NewHash([32]byte{0x02}), Amount: 3},
1036                                 &UTXO{OutputID: bc.NewHash([32]byte{0x03}), Amount: 5},
1037                         },
1038                         inputAmount: 13,
1039                         wantUtxos: []*UTXO{
1040                                 &UTXO{OutputID: bc.NewHash([32]byte{0x03}), Amount: 5},
1041                                 &UTXO{OutputID: bc.NewHash([32]byte{0x02}), Amount: 3},
1042                         },
1043                         optAmount:      8,
1044                         reservedAmount: 1,
1045                 },
1046                 {
1047                         uk: utxoKeeper{
1048                                 reserved: map[bc.Hash]uint64{
1049                                         bc.NewHash([32]byte{0x01}): 1,
1050                                         bc.NewHash([32]byte{0x02}): 2,
1051                                         bc.NewHash([32]byte{0x03}): 3,
1052                                 },
1053                         },
1054                         input: []*UTXO{
1055                                 &UTXO{OutputID: bc.NewHash([32]byte{0x01}), Amount: 1},
1056                                 &UTXO{OutputID: bc.NewHash([32]byte{0x02}), Amount: 3},
1057                                 &UTXO{OutputID: bc.NewHash([32]byte{0x03}), Amount: 5},
1058                         },
1059                         inputAmount:    1,
1060                         wantUtxos:      []*UTXO{},
1061                         optAmount:      0,
1062                         reservedAmount: 9,
1063                 },
1064                 {
1065                         uk: utxoKeeper{},
1066                         input: []*UTXO{
1067                                 &UTXO{OutputID: bc.NewHash([32]byte{0x01}), Amount: 1},
1068                                 &UTXO{OutputID: bc.NewHash([32]byte{0x02}), Amount: 3},
1069                                 &UTXO{OutputID: bc.NewHash([32]byte{0x03}), Amount: 5},
1070                         },
1071                         inputAmount: 1,
1072                         wantUtxos: []*UTXO{
1073                                 &UTXO{OutputID: bc.NewHash([32]byte{0x01}), Amount: 1},
1074                         },
1075                         optAmount:      1,
1076                         reservedAmount: 0,
1077                 },
1078                 {
1079                         uk: utxoKeeper{},
1080                         input: []*UTXO{
1081                                 &UTXO{OutputID: bc.NewHash([32]byte{0x02}), Amount: 2},
1082                                 &UTXO{OutputID: bc.NewHash([32]byte{0x03}), Amount: 3},
1083                                 &UTXO{OutputID: bc.NewHash([32]byte{0x05}), Amount: 5},
1084                         },
1085                         inputAmount: 5,
1086                         wantUtxos: []*UTXO{
1087                                 &UTXO{OutputID: bc.NewHash([32]byte{0x03}), Amount: 3},
1088                                 &UTXO{OutputID: bc.NewHash([32]byte{0x02}), Amount: 2},
1089                         },
1090                         optAmount:      5,
1091                         reservedAmount: 0,
1092                 },
1093                 {
1094                         uk: utxoKeeper{},
1095                         input: []*UTXO{
1096                                 &UTXO{OutputID: bc.NewHash([32]byte{0x01}), Amount: 1},
1097                                 &UTXO{OutputID: bc.NewHash([32]byte{0x02}), Amount: 1},
1098                                 &UTXO{OutputID: bc.NewHash([32]byte{0x03}), Amount: 1},
1099                                 &UTXO{OutputID: bc.NewHash([32]byte{0x04}), Amount: 1},
1100                                 &UTXO{OutputID: bc.NewHash([32]byte{0x05}), Amount: 1},
1101                                 &UTXO{OutputID: bc.NewHash([32]byte{0x06}), Amount: 1},
1102                                 &UTXO{OutputID: bc.NewHash([32]byte{0x08}), Amount: 6},
1103                         },
1104                         inputAmount: 6,
1105                         wantUtxos: []*UTXO{
1106                                 &UTXO{OutputID: bc.NewHash([32]byte{0x08}), Amount: 6},
1107                         },
1108                         optAmount:      6,
1109                         reservedAmount: 0,
1110                 },
1111                 {
1112                         uk: utxoKeeper{},
1113                         input: []*UTXO{
1114                                 &UTXO{OutputID: bc.NewHash([32]byte{0x01}), Amount: 1},
1115                                 &UTXO{OutputID: bc.NewHash([32]byte{0x02}), Amount: 1},
1116                                 &UTXO{OutputID: bc.NewHash([32]byte{0x03}), Amount: 1},
1117                                 &UTXO{OutputID: bc.NewHash([32]byte{0x04}), Amount: 1},
1118                                 &UTXO{OutputID: bc.NewHash([32]byte{0x05}), Amount: 1},
1119                                 &UTXO{OutputID: bc.NewHash([32]byte{0x06}), Amount: 1},
1120                                 &UTXO{OutputID: bc.NewHash([32]byte{0x08}), Amount: 6},
1121                         },
1122                         inputAmount: 5,
1123                         wantUtxos: []*UTXO{
1124                                 &UTXO{OutputID: bc.NewHash([32]byte{0x03}), Amount: 1},
1125                                 &UTXO{OutputID: bc.NewHash([32]byte{0x04}), Amount: 1},
1126                                 &UTXO{OutputID: bc.NewHash([32]byte{0x05}), Amount: 1},
1127                                 &UTXO{OutputID: bc.NewHash([32]byte{0x06}), Amount: 1},
1128                                 &UTXO{OutputID: bc.NewHash([32]byte{0x01}), Amount: 1},
1129                         },
1130                         optAmount:      5,
1131                         reservedAmount: 0,
1132                 },
1133                 {
1134                         uk: utxoKeeper{},
1135                         input: []*UTXO{
1136                                 &UTXO{OutputID: bc.NewHash([32]byte{0x01}), Amount: 1},
1137                                 &UTXO{OutputID: bc.NewHash([32]byte{0x03}), Amount: 3},
1138                                 &UTXO{OutputID: bc.NewHash([32]byte{0x05}), Amount: 5},
1139                                 &UTXO{OutputID: bc.NewHash([32]byte{0x07}), Amount: 7},
1140                                 &UTXO{OutputID: bc.NewHash([32]byte{0x11}), Amount: 11},
1141                                 &UTXO{OutputID: bc.NewHash([32]byte{0x13}), Amount: 13},
1142                                 &UTXO{OutputID: bc.NewHash([32]byte{0x23}), Amount: 23},
1143                                 &UTXO{OutputID: bc.NewHash([32]byte{0x31}), Amount: 31},
1144                         },
1145                         inputAmount: 13,
1146                         wantUtxos: []*UTXO{
1147                                 &UTXO{OutputID: bc.NewHash([32]byte{0x07}), Amount: 7},
1148                                 &UTXO{OutputID: bc.NewHash([32]byte{0x05}), Amount: 5},
1149                                 &UTXO{OutputID: bc.NewHash([32]byte{0x03}), Amount: 3},
1150                         },
1151                         optAmount:      15,
1152                         reservedAmount: 0,
1153                 },
1154                 {
1155                         uk: utxoKeeper{},
1156                         input: []*UTXO{
1157                                 &UTXO{OutputID: bc.NewHash([32]byte{0x01}), Amount: 1},
1158                         },
1159                         inputAmount: 1,
1160                         wantUtxos: []*UTXO{
1161                                 &UTXO{OutputID: bc.NewHash([32]byte{0x01}), Amount: 1},
1162                         },
1163                         optAmount:      1,
1164                         reservedAmount: 0,
1165                 },
1166                 {
1167                         uk: utxoKeeper{},
1168                         input: []*UTXO{
1169                                 &UTXO{OutputID: bc.NewHash([32]byte{0x01}), Amount: 1},
1170                                 &UTXO{OutputID: bc.NewHash([32]byte{0x02}), Amount: 2},
1171                                 &UTXO{OutputID: bc.NewHash([32]byte{0x03}), Amount: 3},
1172                                 &UTXO{OutputID: bc.NewHash([32]byte{0x04}), Amount: 4},
1173                                 &UTXO{OutputID: bc.NewHash([32]byte{0x05}), Amount: 5},
1174                                 &UTXO{OutputID: bc.NewHash([32]byte{0x06}), Amount: 6},
1175                                 &UTXO{OutputID: bc.NewHash([32]byte{0x07}), Amount: 7},
1176                                 &UTXO{OutputID: bc.NewHash([32]byte{0x08}), Amount: 8},
1177                                 &UTXO{OutputID: bc.NewHash([32]byte{0x09}), Amount: 9},
1178                                 &UTXO{OutputID: bc.NewHash([32]byte{0x10}), Amount: 10},
1179                                 &UTXO{OutputID: bc.NewHash([32]byte{0x11}), Amount: 11},
1180                                 &UTXO{OutputID: bc.NewHash([32]byte{0x12}), Amount: 12},
1181                         },
1182                         inputAmount: 15,
1183                         wantUtxos: []*UTXO{
1184                                 &UTXO{OutputID: bc.NewHash([32]byte{0x05}), Amount: 5},
1185                                 &UTXO{OutputID: bc.NewHash([32]byte{0x04}), Amount: 4},
1186                                 &UTXO{OutputID: bc.NewHash([32]byte{0x03}), Amount: 3},
1187                                 &UTXO{OutputID: bc.NewHash([32]byte{0x02}), Amount: 2},
1188                                 &UTXO{OutputID: bc.NewHash([32]byte{0x01}), Amount: 1},
1189                         },
1190                         optAmount:      15,
1191                         reservedAmount: 0,
1192                 },
1193         }
1194
1195         for i, c := range cases {
1196                 got, optAmount, reservedAmount := c.uk.optUTXOs(c.input, c.inputAmount)
1197                 if !testutil.DeepEqual(got, c.wantUtxos) {
1198                         t.Errorf("case %d: utxos got %v want %v", i, got, c.wantUtxos)
1199                 }
1200                 if optAmount != c.optAmount {
1201                         t.Errorf("case %d: utxos got %v want %v", i, optAmount, c.optAmount)
1202                 }
1203                 if reservedAmount != c.reservedAmount {
1204                         t.Errorf("case %d: reservedAmount got %v want %v", i, reservedAmount, c.reservedAmount)
1205                 }
1206         }
1207 }
1208
1209 func checkUtxoKeeperEqual(t *testing.T, i int, a, b *utxoKeeper) {
1210         if !testutil.DeepEqual(a.unconfirmed, b.unconfirmed) {
1211                 t.Errorf("case %d: unconfirmed got %v want %v", i, a.unconfirmed, b.unconfirmed)
1212         }
1213         if !testutil.DeepEqual(a.reserved, b.reserved) {
1214                 t.Errorf("case %d: reserved got %v want %v", i, a.reserved, b.reserved)
1215         }
1216         if !testutil.DeepEqual(a.reservations, b.reservations) {
1217                 t.Errorf("case %d: reservations got %v want %v", i, a.reservations, b.reservations)
1218         }
1219 }