OSDN Git Service

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