9 dbm "github.com/vapor/database/leveldb"
10 "github.com/vapor/protocol/bc"
11 "github.com/vapor/testutil"
14 func TestAddUnconfirmedUtxo(t *testing.T) {
22 unconfirmed: map[bc.Hash]*UTXO{},
25 unconfirmed: map[bc.Hash]*UTXO{},
31 unconfirmed: map[bc.Hash]*UTXO{},
34 unconfirmed: map[bc.Hash]*UTXO{
35 bc.NewHash([32]byte{0x01}): &UTXO{OutputID: bc.NewHash([32]byte{0x01})},
39 &UTXO{OutputID: bc.NewHash([32]byte{0x01})},
44 unconfirmed: map[bc.Hash]*UTXO{
45 bc.NewHash([32]byte{0x01}): &UTXO{OutputID: bc.NewHash([32]byte{0x01})},
49 unconfirmed: map[bc.Hash]*UTXO{
50 bc.NewHash([32]byte{0x01}): &UTXO{OutputID: bc.NewHash([32]byte{0x01})},
54 &UTXO{OutputID: bc.NewHash([32]byte{0x01})},
59 unconfirmed: map[bc.Hash]*UTXO{
60 bc.NewHash([32]byte{0x01}): &UTXO{OutputID: bc.NewHash([32]byte{0x01})},
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})},
71 &UTXO{OutputID: bc.NewHash([32]byte{0x02})},
72 &UTXO{OutputID: bc.NewHash([32]byte{0x03})},
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)
85 func TestCancel(t *testing.T) {
93 reserved: map[bc.Hash]uint64{},
94 reservations: map[uint64]*reservation{},
97 reserved: map[bc.Hash]uint64{},
98 reservations: map[uint64]*reservation{},
104 reserved: map[bc.Hash]uint64{
105 bc.NewHash([32]byte{0x01}): 1,
107 reservations: map[uint64]*reservation{
111 &UTXO{OutputID: bc.NewHash([32]byte{0x01})},
114 expiry: time.Date(2016, 8, 10, 0, 0, 0, 0, time.UTC),
119 reserved: map[bc.Hash]uint64{},
120 reservations: map[uint64]*reservation{},
126 reserved: map[bc.Hash]uint64{
127 bc.NewHash([32]byte{0x01}): 1,
129 reservations: map[uint64]*reservation{
133 &UTXO{OutputID: bc.NewHash([32]byte{0x01})},
136 expiry: time.Date(2016, 8, 10, 0, 0, 0, 0, time.UTC),
141 reserved: map[bc.Hash]uint64{
142 bc.NewHash([32]byte{0x01}): 1,
144 reservations: map[uint64]*reservation{
148 &UTXO{OutputID: bc.NewHash([32]byte{0x01})},
151 expiry: time.Date(2016, 8, 10, 0, 0, 0, 0, time.UTC),
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,
165 reservations: map[uint64]*reservation{
169 &UTXO{OutputID: bc.NewHash([32]byte{0x01})},
172 expiry: time.Date(2016, 8, 10, 0, 0, 0, 0, time.UTC),
177 &UTXO{OutputID: bc.NewHash([32]byte{0x02})},
178 &UTXO{OutputID: bc.NewHash([32]byte{0x03})},
179 &UTXO{OutputID: bc.NewHash([32]byte{0x04})},
182 expiry: time.Date(2016, 8, 10, 0, 0, 0, 0, time.UTC),
187 reserved: map[bc.Hash]uint64{
188 bc.NewHash([32]byte{0x01}): 1,
190 reservations: map[uint64]*reservation{
194 &UTXO{OutputID: bc.NewHash([32]byte{0x01})},
197 expiry: time.Date(2016, 8, 10, 0, 0, 0, 0, time.UTC),
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)
213 func TestRemoveUnconfirmedUtxo(t *testing.T) {
217 removeUtxos []*bc.Hash
221 unconfirmed: map[bc.Hash]*UTXO{},
224 unconfirmed: map[bc.Hash]*UTXO{},
226 removeUtxos: []*bc.Hash{},
230 unconfirmed: map[bc.Hash]*UTXO{
231 bc.Hash{V0: 1}: &UTXO{OutputID: bc.NewHash([32]byte{0x01})},
235 unconfirmed: map[bc.Hash]*UTXO{},
237 removeUtxos: []*bc.Hash{
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})},
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})},
257 removeUtxos: []*bc.Hash{
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)
273 func TestReserve(t *testing.T) {
274 currentHeight := func() uint64 { return 9527 }
275 testDB := dbm.NewDB("testdb", "leveldb", "temp")
292 currentHeight: currentHeight,
293 reserved: map[bc.Hash]uint64{},
294 reservations: map[uint64]*reservation{},
298 currentHeight: currentHeight,
299 reserved: map[bc.Hash]uint64{},
300 reservations: map[uint64]*reservation{},
303 err: ErrInsufficient,
308 currentHeight: currentHeight,
309 unconfirmed: map[bc.Hash]*UTXO{
310 bc.NewHash([32]byte{0x01}): &UTXO{
311 OutputID: bc.NewHash([32]byte{0x01}),
312 AccountID: "testAccount",
316 reserved: map[bc.Hash]uint64{},
317 reservations: map[uint64]*reservation{},
321 currentHeight: currentHeight,
322 unconfirmed: map[bc.Hash]*UTXO{
323 bc.NewHash([32]byte{0x01}): &UTXO{
324 OutputID: bc.NewHash([32]byte{0x01}),
325 AccountID: "testAccount",
329 reserved: map[bc.Hash]uint64{},
330 reservations: map[uint64]*reservation{},
333 err: ErrInsufficient,
338 currentHeight: currentHeight,
339 unconfirmed: map[bc.Hash]*UTXO{
340 bc.NewHash([32]byte{0x01}): &UTXO{
341 OutputID: bc.NewHash([32]byte{0x01}),
342 AccountID: "testAccount",
347 reserved: map[bc.Hash]uint64{},
348 reservations: map[uint64]*reservation{},
352 currentHeight: currentHeight,
353 unconfirmed: map[bc.Hash]*UTXO{
354 bc.NewHash([32]byte{0x01}): &UTXO{
355 OutputID: bc.NewHash([32]byte{0x01}),
356 AccountID: "testAccount",
361 reserved: map[bc.Hash]uint64{},
362 reservations: map[uint64]*reservation{},
370 currentHeight: currentHeight,
371 unconfirmed: map[bc.Hash]*UTXO{
372 bc.NewHash([32]byte{0x01}): &UTXO{
373 OutputID: bc.NewHash([32]byte{0x01}),
374 AccountID: "testAccount",
378 reserved: map[bc.Hash]uint64{
379 bc.NewHash([32]byte{0x01}): 0,
381 reservations: map[uint64]*reservation{},
385 currentHeight: currentHeight,
386 unconfirmed: map[bc.Hash]*UTXO{
387 bc.NewHash([32]byte{0x01}): &UTXO{
388 OutputID: bc.NewHash([32]byte{0x01}),
389 AccountID: "testAccount",
393 reserved: map[bc.Hash]uint64{
394 bc.NewHash([32]byte{0x01}): 0,
396 reservations: map[uint64]*reservation{},
404 currentHeight: currentHeight,
405 unconfirmed: map[bc.Hash]*UTXO{
406 bc.NewHash([32]byte{0x01}): &UTXO{
407 OutputID: bc.NewHash([32]byte{0x01}),
408 AccountID: "testAccount",
412 reserved: map[bc.Hash]uint64{},
413 reservations: map[uint64]*reservation{},
417 currentHeight: currentHeight,
418 unconfirmed: map[bc.Hash]*UTXO{
419 bc.NewHash([32]byte{0x01}): &UTXO{
420 OutputID: bc.NewHash([32]byte{0x01}),
421 AccountID: "testAccount",
425 reserved: map[bc.Hash]uint64{
426 bc.NewHash([32]byte{0x01}): 1,
428 reservations: map[uint64]*reservation{
433 OutputID: bc.NewHash([32]byte{0x01}),
434 AccountID: "testAccount",
439 expiry: time.Date(2016, 8, 10, 0, 0, 0, 0, time.UTC),
445 exp: time.Date(2016, 8, 10, 0, 0, 0, 0, time.UTC),
450 currentHeight: currentHeight,
452 unconfirmed: map[bc.Hash]*UTXO{
453 bc.NewHash([32]byte{0x01}): &UTXO{
454 OutputID: bc.NewHash([32]byte{0x01}),
455 AccountID: "testAccount",
458 bc.NewHash([32]byte{0x02}): &UTXO{
459 OutputID: bc.NewHash([32]byte{0x02}),
460 AccountID: "testAccount",
463 bc.NewHash([32]byte{0x03}): &UTXO{
464 OutputID: bc.NewHash([32]byte{0x03}),
465 AccountID: "testAccount",
469 reserved: map[bc.Hash]uint64{
470 bc.NewHash([32]byte{0x01}): 1,
472 reservations: map[uint64]*reservation{},
476 currentHeight: currentHeight,
477 unconfirmed: map[bc.Hash]*UTXO{
478 bc.NewHash([32]byte{0x01}): &UTXO{
479 OutputID: bc.NewHash([32]byte{0x01}),
480 AccountID: "testAccount",
483 bc.NewHash([32]byte{0x02}): &UTXO{
484 OutputID: bc.NewHash([32]byte{0x02}),
485 AccountID: "testAccount",
488 bc.NewHash([32]byte{0x03}): &UTXO{
489 OutputID: bc.NewHash([32]byte{0x03}),
490 AccountID: "testAccount",
494 reserved: map[bc.Hash]uint64{
495 bc.NewHash([32]byte{0x01}): 1,
496 bc.NewHash([32]byte{0x02}): 2,
497 bc.NewHash([32]byte{0x03}): 2,
499 reservations: map[uint64]*reservation{
504 OutputID: bc.NewHash([32]byte{0x03}),
505 AccountID: "testAccount",
509 OutputID: bc.NewHash([32]byte{0x02}),
510 AccountID: "testAccount",
515 expiry: time.Date(2016, 8, 10, 0, 0, 0, 0, time.UTC),
521 exp: time.Date(2016, 8, 10, 0, 0, 0, 0, time.UTC),
526 currentHeight: currentHeight,
527 unconfirmed: map[bc.Hash]*UTXO{
528 bc.NewHash([32]byte{0x01}): &UTXO{
529 OutputID: bc.NewHash([32]byte{0x01}),
530 AccountID: "testAccount",
532 Vote: []byte("af594006a40837d9f028daabb6d589df0b9138daefad5683e5233c2646279217294a8d532e60863bcf196625a35fb8ceeffa3c09610eb92dcfb655a947f13269"),
535 reserved: map[bc.Hash]uint64{},
536 reservations: map[uint64]*reservation{},
540 currentHeight: currentHeight,
541 unconfirmed: map[bc.Hash]*UTXO{
542 bc.NewHash([32]byte{0x01}): &UTXO{
543 OutputID: bc.NewHash([32]byte{0x01}),
544 AccountID: "testAccount",
546 Vote: []byte("af594006a40837d9f028daabb6d589df0b9138daefad5683e5233c2646279217294a8d532e60863bcf196625a35fb8ceeffa3c09610eb92dcfb655a947f13269"),
549 reserved: map[bc.Hash]uint64{
550 bc.NewHash([32]byte{0x01}): 1,
552 reservations: map[uint64]*reservation{
557 OutputID: bc.NewHash([32]byte{0x01}),
558 AccountID: "testAccount",
560 Vote: []byte("af594006a40837d9f028daabb6d589df0b9138daefad5683e5233c2646279217294a8d532e60863bcf196625a35fb8ceeffa3c09610eb92dcfb655a947f13269"),
564 expiry: time.Date(2016, 8, 10, 0, 0, 0, 0, time.UTC),
570 exp: time.Date(2016, 8, 10, 0, 0, 0, 0, time.UTC),
571 vote: []byte("af594006a40837d9f028daabb6d589df0b9138daefad5683e5233c2646279217294a8d532e60863bcf196625a35fb8ceeffa3c09610eb92dcfb655a947f13269"),
575 for i, c := range cases {
576 if _, err := c.before.Reserve("testAccount", &bc.AssetID{}, c.reserveAmount, true, c.vote, c.exp); err != c.err {
577 t.Errorf("case %d: got error %v want error %v", i, err, c.err)
579 checkUtxoKeeperEqual(t, i, &c.before, &c.after)
583 func TestReserveParticular(t *testing.T) {
584 currentHeight := func() uint64 { return 9527 }
585 testDB := dbm.NewDB("testdb", "leveldb", "temp")
586 defer os.RemoveAll("temp")
598 currentHeight: currentHeight,
599 unconfirmed: map[bc.Hash]*UTXO{
600 bc.NewHash([32]byte{0x01}): &UTXO{
601 OutputID: bc.NewHash([32]byte{0x01}),
602 AccountID: "testAccount",
606 reserved: map[bc.Hash]uint64{
607 bc.NewHash([32]byte{0x01}): 0,
609 reservations: map[uint64]*reservation{},
613 currentHeight: currentHeight,
614 unconfirmed: map[bc.Hash]*UTXO{
615 bc.NewHash([32]byte{0x01}): &UTXO{
616 OutputID: bc.NewHash([32]byte{0x01}),
617 AccountID: "testAccount",
621 reserved: map[bc.Hash]uint64{
622 bc.NewHash([32]byte{0x01}): 0,
624 reservations: map[uint64]*reservation{},
626 reserveHash: bc.NewHash([32]byte{0x01}),
632 currentHeight: currentHeight,
633 unconfirmed: map[bc.Hash]*UTXO{
634 bc.NewHash([32]byte{0x01}): &UTXO{
635 OutputID: bc.NewHash([32]byte{0x01}),
636 AccountID: "testAccount",
641 reserved: map[bc.Hash]uint64{},
642 reservations: map[uint64]*reservation{},
646 currentHeight: currentHeight,
647 unconfirmed: map[bc.Hash]*UTXO{
648 bc.NewHash([32]byte{0x01}): &UTXO{
649 OutputID: bc.NewHash([32]byte{0x01}),
650 AccountID: "testAccount",
655 reserved: map[bc.Hash]uint64{},
656 reservations: map[uint64]*reservation{},
658 reserveHash: bc.NewHash([32]byte{0x01}),
664 currentHeight: currentHeight,
665 unconfirmed: map[bc.Hash]*UTXO{
666 bc.NewHash([32]byte{0x01}): &UTXO{
667 OutputID: bc.NewHash([32]byte{0x01}),
668 AccountID: "testAccount",
672 reserved: map[bc.Hash]uint64{},
673 reservations: map[uint64]*reservation{},
677 currentHeight: currentHeight,
678 unconfirmed: map[bc.Hash]*UTXO{
679 bc.NewHash([32]byte{0x01}): &UTXO{
680 OutputID: bc.NewHash([32]byte{0x01}),
681 AccountID: "testAccount",
685 reserved: map[bc.Hash]uint64{
686 bc.NewHash([32]byte{0x01}): 1,
688 reservations: map[uint64]*reservation{
693 OutputID: bc.NewHash([32]byte{0x01}),
694 AccountID: "testAccount",
699 expiry: time.Date(2016, 8, 10, 0, 0, 0, 0, time.UTC),
703 reserveHash: bc.NewHash([32]byte{0x01}),
705 exp: time.Date(2016, 8, 10, 0, 0, 0, 0, time.UTC),
709 for i, c := range cases {
710 if _, err := c.before.ReserveParticular(c.reserveHash, true, c.exp); err != c.err {
711 t.Errorf("case %d: got error %v want error %v", i, err, c.err)
713 checkUtxoKeeperEqual(t, i, &c.before, &c.after)
717 func TestExpireReservation(t *testing.T) {
718 before := &utxoKeeper{
719 reservations: map[uint64]*reservation{
720 1: &reservation{expiry: time.Date(2016, 8, 10, 0, 0, 0, 0, time.UTC)},
721 2: &reservation{expiry: time.Date(3016, 8, 10, 0, 0, 0, 0, time.UTC)},
722 3: &reservation{expiry: time.Date(2016, 8, 10, 0, 0, 0, 0, time.UTC)},
723 4: &reservation{expiry: time.Date(3016, 8, 10, 0, 0, 0, 0, time.UTC)},
724 5: &reservation{expiry: time.Date(3016, 8, 10, 0, 0, 0, 0, time.UTC)},
727 after := &utxoKeeper{
728 reservations: map[uint64]*reservation{
729 2: &reservation{expiry: time.Date(3016, 8, 10, 0, 0, 0, 0, time.UTC)},
730 4: &reservation{expiry: time.Date(3016, 8, 10, 0, 0, 0, 0, time.UTC)},
731 5: &reservation{expiry: time.Date(3016, 8, 10, 0, 0, 0, 0, time.UTC)},
734 before.expireReservation(time.Date(2017, 8, 10, 0, 0, 0, 0, time.UTC))
735 checkUtxoKeeperEqual(t, 0, before, after)
738 func TestFindUtxos(t *testing.T) {
739 currentHeight := func() uint64 { return 9527 }
740 testDB := dbm.NewDB("testdb", "leveldb", "temp")
751 immatureAmount uint64
757 currentHeight: currentHeight,
758 unconfirmed: map[bc.Hash]*UTXO{},
761 useUnconfirmed: true,
762 wantUtxos: []*UTXO{},
768 currentHeight: currentHeight,
769 unconfirmed: map[bc.Hash]*UTXO{},
773 OutputID: bc.NewHash([32]byte{0x01}),
774 AccountID: "testAccount",
778 OutputID: bc.NewHash([32]byte{0x02}),
779 AccountID: "testAccount",
780 AssetID: bc.AssetID{V0: 6},
784 useUnconfirmed: false,
787 OutputID: bc.NewHash([32]byte{0x01}),
788 AccountID: "testAccount",
797 currentHeight: currentHeight,
798 unconfirmed: map[bc.Hash]*UTXO{},
802 OutputID: bc.NewHash([32]byte{0x02}),
803 AccountID: "testAccount",
808 useUnconfirmed: false,
809 wantUtxos: []*UTXO{},
815 currentHeight: currentHeight,
816 unconfirmed: map[bc.Hash]*UTXO{
817 bc.NewHash([32]byte{0x01}): &UTXO{
818 OutputID: bc.NewHash([32]byte{0x01}),
819 AccountID: "testAccount",
826 OutputID: bc.NewHash([32]byte{0x02}),
827 AccountID: "testAccount",
831 useUnconfirmed: false,
834 OutputID: bc.NewHash([32]byte{0x02}),
835 AccountID: "testAccount",
844 currentHeight: currentHeight,
845 unconfirmed: map[bc.Hash]*UTXO{
846 bc.NewHash([32]byte{0x11}): &UTXO{
847 OutputID: bc.NewHash([32]byte{0x01}),
848 AccountID: "testAccount",
855 OutputID: bc.NewHash([32]byte{0x02}),
856 AccountID: "testAccount",
860 useUnconfirmed: true,
863 OutputID: bc.NewHash([32]byte{0x02}),
864 AccountID: "testAccount",
868 OutputID: bc.NewHash([32]byte{0x01}),
869 AccountID: "testAccount",
878 currentHeight: currentHeight,
879 unconfirmed: map[bc.Hash]*UTXO{
880 bc.NewHash([32]byte{0x01}): &UTXO{
881 OutputID: bc.NewHash([32]byte{0x01}),
882 AccountID: "testAccount",
885 bc.NewHash([32]byte{0x02}): &UTXO{
886 OutputID: bc.NewHash([32]byte{0x02}),
894 OutputID: bc.NewHash([32]byte{0x03}),
895 AccountID: "testAccount",
899 OutputID: bc.NewHash([32]byte{0x04}),
904 useUnconfirmed: true,
907 OutputID: bc.NewHash([32]byte{0x03}),
908 AccountID: "testAccount",
912 OutputID: bc.NewHash([32]byte{0x01}),
913 AccountID: "testAccount",
922 currentHeight: currentHeight,
923 unconfirmed: map[bc.Hash]*UTXO{},
927 OutputID: bc.NewHash([32]byte{0x01}),
928 AccountID: "testAccount",
930 Vote: []byte("af594006a40837d9f028daabb6d589df0b9138daefad5683e5233c2646279217294a8d532e60863bcf196625a35fb8ceeffa3c09610eb92dcfb655a947f13269"),
933 useUnconfirmed: false,
936 OutputID: bc.NewHash([32]byte{0x01}),
937 AccountID: "testAccount",
939 Vote: []byte("af594006a40837d9f028daabb6d589df0b9138daefad5683e5233c2646279217294a8d532e60863bcf196625a35fb8ceeffa3c09610eb92dcfb655a947f13269"),
943 vote: []byte("af594006a40837d9f028daabb6d589df0b9138daefad5683e5233c2646279217294a8d532e60863bcf196625a35fb8ceeffa3c09610eb92dcfb655a947f13269"),
947 for i, c := range cases {
948 for _, u := range c.dbUtxos {
949 data, err := json.Marshal(u)
953 testDB.Set(StandardUTXOKey(u.OutputID), data)
956 gotUtxos, immatureAmount := c.uk.findUtxos("testAccount", &bc.AssetID{}, c.useUnconfirmed, c.vote)
957 if !testutil.DeepEqual(gotUtxos, c.wantUtxos) {
958 t.Errorf("case %d: got %v want %v", i, gotUtxos, c.wantUtxos)
960 if immatureAmount != c.immatureAmount {
961 t.Errorf("case %d: got %v want %v", i, immatureAmount, c.immatureAmount)
964 for _, u := range c.dbUtxos {
965 testDB.Delete(StandardUTXOKey(u.OutputID))
970 func TestFindUtxo(t *testing.T) {
971 currentHeight := func() uint64 { return 9527 }
972 testDB := dbm.NewDB("testdb", "leveldb", "temp")
973 defer os.RemoveAll("temp")
977 dbUtxos map[string]*UTXO
986 currentHeight: currentHeight,
987 unconfirmed: map[bc.Hash]*UTXO{},
989 dbUtxos: map[string]*UTXO{},
990 outHash: bc.NewHash([32]byte{0x01}),
997 currentHeight: currentHeight,
998 unconfirmed: map[bc.Hash]*UTXO{
999 bc.NewHash([32]byte{0x01}): &UTXO{OutputID: bc.NewHash([32]byte{0x01})},
1002 dbUtxos: map[string]*UTXO{},
1003 outHash: bc.NewHash([32]byte{0x01}),
1005 useUnconfirmed: false,
1011 currentHeight: currentHeight,
1012 unconfirmed: map[bc.Hash]*UTXO{
1013 bc.NewHash([32]byte{0x01}): &UTXO{OutputID: bc.NewHash([32]byte{0x01})},
1016 dbUtxos: map[string]*UTXO{},
1017 outHash: bc.NewHash([32]byte{0x01}),
1018 wantUtxo: &UTXO{OutputID: bc.NewHash([32]byte{0x01})},
1019 useUnconfirmed: true,
1025 currentHeight: currentHeight,
1026 unconfirmed: map[bc.Hash]*UTXO{},
1028 dbUtxos: map[string]*UTXO{
1029 string(StandardUTXOKey(bc.NewHash([32]byte{0x01}))): &UTXO{OutputID: bc.NewHash([32]byte{0x01})},
1031 outHash: bc.NewHash([32]byte{0x01}),
1032 wantUtxo: &UTXO{OutputID: bc.NewHash([32]byte{0x01})},
1033 useUnconfirmed: false,
1039 currentHeight: currentHeight,
1040 unconfirmed: map[bc.Hash]*UTXO{},
1042 dbUtxos: map[string]*UTXO{
1043 string(ContractUTXOKey(bc.NewHash([32]byte{0x01}))): &UTXO{OutputID: bc.NewHash([32]byte{0x01})},
1045 outHash: bc.NewHash([32]byte{0x01}),
1046 wantUtxo: &UTXO{OutputID: bc.NewHash([32]byte{0x01})},
1047 useUnconfirmed: false,
1052 for i, c := range cases {
1053 for k, u := range c.dbUtxos {
1054 data, err := json.Marshal(u)
1058 testDB.Set([]byte(k), data)
1061 gotUtxo, err := c.uk.findUtxo(c.outHash, c.useUnconfirmed)
1062 if !testutil.DeepEqual(gotUtxo, c.wantUtxo) {
1063 t.Errorf("case %d: got %v want %v", i, gotUtxo, c.wantUtxo)
1066 t.Errorf("case %d: got %v want %v", i, err, c.err)
1069 for _, u := range c.dbUtxos {
1070 testDB.Delete(StandardUTXOKey(u.OutputID))
1075 func TestOptUTXOs(t *testing.T) {
1082 reservedAmount uint64
1086 reserved: map[bc.Hash]uint64{
1087 bc.NewHash([32]byte{0x01}): 1,
1092 wantUtxos: []*UTXO{},
1098 reserved: map[bc.Hash]uint64{
1099 bc.NewHash([32]byte{0x01}): 1,
1103 &UTXO{OutputID: bc.NewHash([32]byte{0x01}), Amount: 1},
1106 wantUtxos: []*UTXO{},
1112 reserved: map[bc.Hash]uint64{
1113 bc.NewHash([32]byte{0x01}): 1,
1117 &UTXO{OutputID: bc.NewHash([32]byte{0x01}), Amount: 1},
1118 &UTXO{OutputID: bc.NewHash([32]byte{0x02}), Amount: 3},
1119 &UTXO{OutputID: bc.NewHash([32]byte{0x03}), Amount: 5},
1123 &UTXO{OutputID: bc.NewHash([32]byte{0x03}), Amount: 5},
1124 &UTXO{OutputID: bc.NewHash([32]byte{0x02}), Amount: 3},
1131 reserved: map[bc.Hash]uint64{
1132 bc.NewHash([32]byte{0x01}): 1,
1133 bc.NewHash([32]byte{0x02}): 2,
1134 bc.NewHash([32]byte{0x03}): 3,
1138 &UTXO{OutputID: bc.NewHash([32]byte{0x01}), Amount: 1},
1139 &UTXO{OutputID: bc.NewHash([32]byte{0x02}), Amount: 3},
1140 &UTXO{OutputID: bc.NewHash([32]byte{0x03}), Amount: 5},
1143 wantUtxos: []*UTXO{},
1150 &UTXO{OutputID: bc.NewHash([32]byte{0x01}), Amount: 1},
1151 &UTXO{OutputID: bc.NewHash([32]byte{0x02}), Amount: 3},
1152 &UTXO{OutputID: bc.NewHash([32]byte{0x03}), Amount: 5},
1156 &UTXO{OutputID: bc.NewHash([32]byte{0x01}), Amount: 1},
1164 &UTXO{OutputID: bc.NewHash([32]byte{0x02}), Amount: 2},
1165 &UTXO{OutputID: bc.NewHash([32]byte{0x03}), Amount: 3},
1166 &UTXO{OutputID: bc.NewHash([32]byte{0x05}), Amount: 5},
1170 &UTXO{OutputID: bc.NewHash([32]byte{0x03}), Amount: 3},
1171 &UTXO{OutputID: bc.NewHash([32]byte{0x02}), Amount: 2},
1179 &UTXO{OutputID: bc.NewHash([32]byte{0x01}), Amount: 1},
1180 &UTXO{OutputID: bc.NewHash([32]byte{0x02}), Amount: 1},
1181 &UTXO{OutputID: bc.NewHash([32]byte{0x03}), Amount: 1},
1182 &UTXO{OutputID: bc.NewHash([32]byte{0x04}), Amount: 1},
1183 &UTXO{OutputID: bc.NewHash([32]byte{0x05}), Amount: 1},
1184 &UTXO{OutputID: bc.NewHash([32]byte{0x06}), Amount: 1},
1185 &UTXO{OutputID: bc.NewHash([32]byte{0x08}), Amount: 6},
1189 &UTXO{OutputID: bc.NewHash([32]byte{0x08}), Amount: 6},
1197 &UTXO{OutputID: bc.NewHash([32]byte{0x01}), Amount: 1},
1198 &UTXO{OutputID: bc.NewHash([32]byte{0x02}), Amount: 1},
1199 &UTXO{OutputID: bc.NewHash([32]byte{0x03}), Amount: 1},
1200 &UTXO{OutputID: bc.NewHash([32]byte{0x04}), Amount: 1},
1201 &UTXO{OutputID: bc.NewHash([32]byte{0x05}), Amount: 1},
1202 &UTXO{OutputID: bc.NewHash([32]byte{0x06}), Amount: 1},
1203 &UTXO{OutputID: bc.NewHash([32]byte{0x08}), Amount: 6},
1207 &UTXO{OutputID: bc.NewHash([32]byte{0x03}), Amount: 1},
1208 &UTXO{OutputID: bc.NewHash([32]byte{0x04}), Amount: 1},
1209 &UTXO{OutputID: bc.NewHash([32]byte{0x05}), Amount: 1},
1210 &UTXO{OutputID: bc.NewHash([32]byte{0x06}), Amount: 1},
1211 &UTXO{OutputID: bc.NewHash([32]byte{0x01}), Amount: 1},
1219 &UTXO{OutputID: bc.NewHash([32]byte{0x01}), Amount: 1},
1220 &UTXO{OutputID: bc.NewHash([32]byte{0x03}), Amount: 3},
1221 &UTXO{OutputID: bc.NewHash([32]byte{0x05}), Amount: 5},
1222 &UTXO{OutputID: bc.NewHash([32]byte{0x07}), Amount: 7},
1223 &UTXO{OutputID: bc.NewHash([32]byte{0x11}), Amount: 11},
1224 &UTXO{OutputID: bc.NewHash([32]byte{0x13}), Amount: 13},
1225 &UTXO{OutputID: bc.NewHash([32]byte{0x23}), Amount: 23},
1226 &UTXO{OutputID: bc.NewHash([32]byte{0x31}), Amount: 31},
1230 &UTXO{OutputID: bc.NewHash([32]byte{0x07}), Amount: 7},
1231 &UTXO{OutputID: bc.NewHash([32]byte{0x05}), Amount: 5},
1232 &UTXO{OutputID: bc.NewHash([32]byte{0x03}), Amount: 3},
1240 &UTXO{OutputID: bc.NewHash([32]byte{0x01}), Amount: 1},
1244 &UTXO{OutputID: bc.NewHash([32]byte{0x01}), Amount: 1},
1252 &UTXO{OutputID: bc.NewHash([32]byte{0x01}), Amount: 1},
1253 &UTXO{OutputID: bc.NewHash([32]byte{0x02}), Amount: 2},
1254 &UTXO{OutputID: bc.NewHash([32]byte{0x03}), Amount: 3},
1255 &UTXO{OutputID: bc.NewHash([32]byte{0x04}), Amount: 4},
1256 &UTXO{OutputID: bc.NewHash([32]byte{0x05}), Amount: 5},
1257 &UTXO{OutputID: bc.NewHash([32]byte{0x06}), Amount: 6},
1258 &UTXO{OutputID: bc.NewHash([32]byte{0x07}), Amount: 7},
1259 &UTXO{OutputID: bc.NewHash([32]byte{0x08}), Amount: 8},
1260 &UTXO{OutputID: bc.NewHash([32]byte{0x09}), Amount: 9},
1261 &UTXO{OutputID: bc.NewHash([32]byte{0x10}), Amount: 10},
1262 &UTXO{OutputID: bc.NewHash([32]byte{0x11}), Amount: 11},
1263 &UTXO{OutputID: bc.NewHash([32]byte{0x12}), Amount: 12},
1267 &UTXO{OutputID: bc.NewHash([32]byte{0x05}), Amount: 5},
1268 &UTXO{OutputID: bc.NewHash([32]byte{0x04}), Amount: 4},
1269 &UTXO{OutputID: bc.NewHash([32]byte{0x03}), Amount: 3},
1270 &UTXO{OutputID: bc.NewHash([32]byte{0x02}), Amount: 2},
1271 &UTXO{OutputID: bc.NewHash([32]byte{0x01}), Amount: 1},
1278 for i, c := range cases {
1279 got, optAmount, reservedAmount := c.uk.optUTXOs(c.input, c.inputAmount)
1280 if !testutil.DeepEqual(got, c.wantUtxos) {
1281 t.Errorf("case %d: utxos got %v want %v", i, got, c.wantUtxos)
1283 if optAmount != c.optAmount {
1284 t.Errorf("case %d: utxos got %v want %v", i, optAmount, c.optAmount)
1286 if reservedAmount != c.reservedAmount {
1287 t.Errorf("case %d: reservedAmount got %v want %v", i, reservedAmount, c.reservedAmount)
1292 func checkUtxoKeeperEqual(t *testing.T, i int, a, b *utxoKeeper) {
1293 if !testutil.DeepEqual(a.unconfirmed, b.unconfirmed) {
1294 t.Errorf("case %d: unconfirmed got %v want %v", i, a.unconfirmed, b.unconfirmed)
1296 if !testutil.DeepEqual(a.reserved, b.reserved) {
1297 t.Errorf("case %d: reserved got %v want %v", i, a.reserved, b.reserved)
1299 if !testutil.DeepEqual(a.reservations, b.reservations) {
1300 t.Errorf("case %d: reservations got %v want %v", i, a.reservations, b.reservations)