OSDN Git Service

fix log
[bytom/vapor.git] / database / wallet_store_test.go
1 package database
2
3 import (
4         "bytes"
5         "encoding/hex"
6         "encoding/json"
7         "io/ioutil"
8         "os"
9         "reflect"
10         "sort"
11         "testing"
12
13         acc "github.com/vapor/account"
14         "github.com/vapor/asset"
15         "github.com/vapor/blockchain/pseudohsm"
16         "github.com/vapor/blockchain/query"
17         "github.com/vapor/crypto/ed25519/chainkd"
18         dbm "github.com/vapor/database/leveldb"
19         "github.com/vapor/protocol/bc"
20         "github.com/vapor/testutil"
21         "github.com/vapor/wallet"
22 )
23
24 func TestAccountIndexKey(t *testing.T) {
25         dirPath, err := ioutil.TempDir(".", "TestAccount")
26         if err != nil {
27                 t.Fatal(err)
28         }
29         defer os.RemoveAll(dirPath)
30
31         hsm, err := pseudohsm.New(dirPath)
32         if err != nil {
33                 t.Fatal(err)
34         }
35
36         xpub1, _, err := hsm.XCreate("TestAccountIndex1", "password", "en")
37         if err != nil {
38                 t.Fatal(err)
39         }
40
41         xpub2, _, err := hsm.XCreate("TestAccountIndex2", "password", "en")
42         if err != nil {
43                 t.Fatal(err)
44         }
45
46         xpubs1 := []chainkd.XPub{xpub1.XPub, xpub2.XPub}
47         xpubs2 := []chainkd.XPub{xpub2.XPub, xpub1.XPub}
48         if !reflect.DeepEqual(accountIndexKey(xpubs1), accountIndexKey(xpubs2)) {
49                 t.Fatal("accountIndexKey test err")
50         }
51
52         if reflect.DeepEqual(xpubs1, xpubs2) {
53                 t.Fatal("accountIndexKey test err")
54         }
55 }
56
57 func TestDeleteContractUTXO(t *testing.T) {
58         cases := []struct {
59                 utxos      []*acc.UTXO
60                 deleteUTXO *acc.UTXO
61                 want       []*acc.UTXO
62         }{
63                 {
64                         utxos:      []*acc.UTXO{},
65                         deleteUTXO: &acc.UTXO{},
66                         want:       []*acc.UTXO{},
67                 },
68                 {
69                         utxos: []*acc.UTXO{
70                                 &acc.UTXO{
71                                         OutputID: bc.NewHash([32]byte{0x3e, 0x94, 0x5d, 0x35, 0x70, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
72                                 },
73                         },
74                         deleteUTXO: &acc.UTXO{
75                                 OutputID: bc.NewHash([32]byte{0x3e, 0x94, 0x5d, 0x35, 0x70, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
76                         },
77                         want: []*acc.UTXO{},
78                 },
79                 {
80                         utxos: []*acc.UTXO{
81                                 &acc.UTXO{
82                                         OutputID: bc.NewHash([32]byte{0x3e, 0x94, 0x5d, 0x35, 0x70, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
83                                 },
84                                 &acc.UTXO{
85                                         OutputID: bc.NewHash([32]byte{0x2e, 0x94, 0x5d, 0x35, 0x70, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
86                                 },
87                                 &acc.UTXO{
88                                         OutputID: bc.NewHash([32]byte{0x3f, 0x94, 0x5d, 0x35, 0x70, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
89                                 },
90                                 &acc.UTXO{
91                                         OutputID: bc.NewHash([32]byte{0x5e, 0x94, 0x5d, 0x35, 0x70, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
92                                 },
93                                 &acc.UTXO{
94                                         OutputID: bc.NewHash([32]byte{0x6e, 0x94, 0x5d, 0x35, 0x70, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
95                                 },
96                                 &acc.UTXO{
97                                         OutputID: bc.NewHash([32]byte{0x7e, 0x94, 0x5d, 0x35, 0x70, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
98                                 },
99                         },
100                         deleteUTXO: &acc.UTXO{},
101                         want: []*acc.UTXO{
102                                 &acc.UTXO{
103                                         OutputID: bc.NewHash([32]byte{0x3e, 0x94, 0x5d, 0x35, 0x70, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
104                                 },
105                                 &acc.UTXO{
106                                         OutputID: bc.NewHash([32]byte{0x2e, 0x94, 0x5d, 0x35, 0x70, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
107                                 },
108                                 &acc.UTXO{
109                                         OutputID: bc.NewHash([32]byte{0x3f, 0x94, 0x5d, 0x35, 0x70, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
110                                 },
111                                 &acc.UTXO{
112                                         OutputID: bc.NewHash([32]byte{0x5e, 0x94, 0x5d, 0x35, 0x70, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
113                                 },
114                                 &acc.UTXO{
115                                         OutputID: bc.NewHash([32]byte{0x6e, 0x94, 0x5d, 0x35, 0x70, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
116                                 },
117                                 &acc.UTXO{
118                                         OutputID: bc.NewHash([32]byte{0x7e, 0x94, 0x5d, 0x35, 0x70, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
119                                 },
120                         },
121                 },
122                 {
123                         utxos: []*acc.UTXO{},
124                         deleteUTXO: &acc.UTXO{
125                                 OutputID: bc.NewHash([32]byte{0x3e, 0x94, 0x5d, 0x35, 0x70, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
126                         },
127                         want: []*acc.UTXO{},
128                 },
129                 {
130                         utxos: []*acc.UTXO{
131                                 &acc.UTXO{
132                                         OutputID: bc.NewHash([32]byte{0x0e, 0x04, 0x50, 0x35, 0x70, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
133                                 },
134                                 &acc.UTXO{
135                                         OutputID: bc.NewHash([32]byte{0x00, 0x01, 0x02, 0x35, 0x70, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
136                                 },
137                                 &acc.UTXO{
138                                         OutputID: bc.NewHash([32]byte{0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
139                                 },
140                                 &acc.UTXO{
141                                         OutputID: bc.NewHash([32]byte{0x01, 0x01, 0x02, 0x39, 0x70, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
142                                 },
143                         },
144                         deleteUTXO: &acc.UTXO{
145                                 OutputID: bc.NewHash([32]byte{0x01, 0x01, 0x02, 0x39, 0x70, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
146                         },
147                         want: []*acc.UTXO{
148                                 &acc.UTXO{
149                                         OutputID: bc.NewHash([32]byte{0x0e, 0x04, 0x50, 0x35, 0x70, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
150                                 },
151                                 &acc.UTXO{
152                                         OutputID: bc.NewHash([32]byte{0x00, 0x01, 0x02, 0x35, 0x70, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
153                                 },
154                                 &acc.UTXO{
155                                         OutputID: bc.NewHash([32]byte{0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
156                                 },
157                         },
158                 },
159         }
160
161         for _, c := range cases {
162                 testDB := dbm.NewDB("testdb", "leveldb", "temp")
163                 accountStore := NewAccountStore(testDB)
164                 walletStore := NewWalletStore(testDB)
165                 ws := walletStore.InitBatch()
166                 // store mock utxos
167                 for _, utxo := range c.utxos {
168                         if err := ws.SetContractUTXO(utxo.OutputID, utxo); err != nil {
169                                 t.Fatal(err)
170                         }
171                 }
172
173                 // delete utxo
174                 ws.DeleteContractUTXO(c.deleteUTXO.OutputID)
175                 if err := ws.CommitBatch(); err != nil {
176                         t.Fatal(err)
177                 }
178
179                 // get utxo by outputID
180                 for _, utxo := range c.want {
181                         if _, err := accountStore.GetUTXO(utxo.OutputID); err != nil {
182                                 t.Fatal(err)
183                         }
184                 }
185
186                 testDB.Close()
187                 os.RemoveAll("temp")
188         }
189 }
190
191 func TestDeleteRecoveryStatus(t *testing.T) {
192         cases := []struct {
193                 state *wallet.RecoveryState
194         }{
195                 {
196                         state: &wallet.RecoveryState{},
197                 },
198                 {
199                         state: &wallet.RecoveryState{
200                                 XPubs: []chainkd.XPub{
201                                         chainkd.XPub([64]byte{0x00, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c, 0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
202                                 },
203                         },
204                 },
205                 {
206                         state: &wallet.RecoveryState{
207                                 XPubs: []chainkd.XPub{
208                                         chainkd.XPub([64]byte{0x00, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c, 0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
209                                         chainkd.XPub([64]byte{0x01, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c, 0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
210                                         chainkd.XPub([64]byte{0x02, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c, 0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
211                                         chainkd.XPub([64]byte{0x03, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c, 0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
212                                         chainkd.XPub([64]byte{0x04, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c, 0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
213                                         chainkd.XPub([64]byte{0x05, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c, 0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
214                                         chainkd.XPub([64]byte{0x06, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c, 0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
215                                         chainkd.XPub([64]byte{0x07, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c, 0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
216                                         chainkd.XPub([64]byte{0x08, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c, 0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
217                                         chainkd.XPub([64]byte{0x09, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c, 0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
218                                         chainkd.XPub([64]byte{0x0a, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c, 0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
219                                         chainkd.XPub([64]byte{0x0b, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c, 0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
220                                 },
221                         },
222                 },
223         }
224
225         for i, c := range cases {
226                 testDB := dbm.NewDB("testdb", "leveldb", "temp")
227                 walletStore := NewWalletStore(testDB)
228                 ws := walletStore.InitBatch()
229                 if err := ws.SetRecoveryStatus(c.state); err != nil {
230                         t.Fatal(err)
231                 }
232
233                 if err := ws.CommitBatch(); err != nil {
234                         t.Fatal(err)
235                 }
236
237                 gotState, err := ws.GetRecoveryStatus()
238                 if err != nil {
239                         t.Fatal(err)
240                 }
241
242                 if !testutil.DeepEqual(gotState, c.state) {
243                         t.Errorf("case %v: got recovery status, got: %v, want: %v.", i, gotState, c.state)
244                 }
245
246                 ws = walletStore.InitBatch()
247                 ws.DeleteRecoveryStatus()
248                 if err := ws.CommitBatch(); err != nil {
249                         t.Fatal(err)
250                 }
251
252                 gotState, err = ws.GetRecoveryStatus()
253                 if err == nil {
254                         t.Errorf("case %v: got state should fail.", i)
255                 }
256
257                 testDB.Close()
258                 os.RemoveAll("temp")
259         }
260 }
261
262 func TestGetWalletInfo(t *testing.T) {
263         cases := []struct {
264                 state *wallet.StatusInfo
265         }{
266                 {
267                         state: &wallet.StatusInfo{},
268                 },
269                 {
270                         state: &wallet.StatusInfo{
271                                 Version:    uint(0),
272                                 WorkHeight: uint64(9),
273                                 WorkHash:   bc.NewHash([32]byte{0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
274                                 BestHash:   bc.NewHash([32]byte{0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
275                                 BestHeight: uint64(0),
276                         },
277                 },
278                 {
279                         state: &wallet.StatusInfo{
280                                 Version:    uint(9),
281                                 WorkHeight: uint64(9999999),
282                                 WorkHash:   bc.NewHash([32]byte{0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
283                                 BestHash:   bc.NewHash([32]byte{0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
284                                 BestHeight: uint64(100000),
285                         },
286                 },
287         }
288
289         for i, c := range cases {
290                 testDB := dbm.NewDB("testdb", "leveldb", "temp")
291                 walletStore := NewWalletStore(testDB)
292                 ws := walletStore.InitBatch()
293                 if err := ws.SetWalletInfo(c.state); err != nil {
294                         t.Fatal(err)
295                 }
296
297                 if err := ws.CommitBatch(); err != nil {
298                         t.Fatal(err)
299                 }
300
301                 gotState, err := ws.GetWalletInfo()
302                 if err != nil {
303                         t.Fatal(err)
304                 }
305
306                 if !testutil.DeepEqual(gotState, c.state) {
307                         t.Errorf("case %v: got wallet info, got: %v, want: %v.", i, gotState, c.state)
308                 }
309
310                 testDB.Close()
311                 os.RemoveAll("temp")
312         }
313 }
314
315 func TestDeleteUnconfirmedTransaction(t *testing.T) {
316         cases := []struct {
317                 tx *query.AnnotatedTx
318         }{
319                 {
320                         tx: &query.AnnotatedTx{},
321                 },
322                 {
323                         tx: &query.AnnotatedTx{
324                                 ID:          bc.NewHash([32]byte{0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
325                                 Timestamp:   uint64(100),
326                                 BlockID:     bc.NewHash([32]byte{0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
327                                 BlockHeight: uint64(100),
328                                 Position:    uint32(100),
329                         },
330                 },
331         }
332
333         for i, c := range cases {
334                 testDB := dbm.NewDB("testdb", "leveldb", "temp")
335                 walletStore := NewWalletStore(testDB)
336                 ws := walletStore.InitBatch()
337                 if err := ws.SetUnconfirmedTransaction(c.tx.ID.String(), c.tx); err != nil {
338                         t.Fatal(err)
339                 }
340
341                 if err := ws.CommitBatch(); err != nil {
342                         t.Fatal(err)
343                 }
344
345                 gotTx, err := ws.GetUnconfirmedTransaction(c.tx.ID.String())
346                 if err != nil {
347                         t.Fatal(err)
348                 }
349
350                 if !testutil.DeepEqual(gotTx, c.tx) {
351                         t.Errorf("case %v: got unconfirmed transaction, got: %v, want: %v.", i, gotTx, c.tx)
352                 }
353
354                 ws = walletStore.InitBatch()
355                 ws.DeleteUnconfirmedTransaction(c.tx.ID.String())
356                 if err := ws.CommitBatch(); err != nil {
357                         t.Fatal(err)
358                 }
359
360                 gotTx, err = ws.GetUnconfirmedTransaction(c.tx.ID.String())
361                 if err == nil {
362                         t.Errorf("case %v: got unconfirmed transaction should fail.", i)
363                 }
364
365                 testDB.Close()
366                 os.RemoveAll("temp")
367         }
368 }
369
370 func TestListUnconfirmedTransactions(t *testing.T) {
371         cases := []struct {
372                 txs []*query.AnnotatedTx
373         }{
374                 {
375                         txs: []*query.AnnotatedTx{},
376                 },
377                 {
378                         txs: []*query.AnnotatedTx{
379                                 &query.AnnotatedTx{
380                                         ID:          bc.NewHash([32]byte{0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
381                                         Timestamp:   uint64(100),
382                                         BlockID:     bc.NewHash([32]byte{0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
383                                         BlockHeight: uint64(100),
384                                         Position:    uint32(100),
385                                 },
386                         },
387                 },
388                 {
389                         txs: []*query.AnnotatedTx{
390                                 &query.AnnotatedTx{
391                                         ID:          bc.NewHash([32]byte{0x02, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
392                                         Timestamp:   uint64(100),
393                                         BlockID:     bc.NewHash([32]byte{0x02, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
394                                         BlockHeight: uint64(100),
395                                         Position:    uint32(100),
396                                 },
397                                 &query.AnnotatedTx{
398                                         ID:          bc.NewHash([32]byte{0x03, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
399                                         Timestamp:   uint64(100),
400                                         BlockID:     bc.NewHash([32]byte{0x03, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
401                                         BlockHeight: uint64(100),
402                                         Position:    uint32(100),
403                                 },
404                                 &query.AnnotatedTx{
405                                         ID:          bc.NewHash([32]byte{0x04, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
406                                         Timestamp:   uint64(100),
407                                         BlockID:     bc.NewHash([32]byte{0x04, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
408                                         BlockHeight: uint64(100),
409                                         Position:    uint32(100),
410                                 },
411                                 &query.AnnotatedTx{
412                                         ID:          bc.NewHash([32]byte{0x05, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
413                                         Timestamp:   uint64(100),
414                                         BlockID:     bc.NewHash([32]byte{0x05, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
415                                         BlockHeight: uint64(100),
416                                         Position:    uint32(100),
417                                 },
418                                 &query.AnnotatedTx{
419                                         ID:          bc.NewHash([32]byte{0x06, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
420                                         Timestamp:   uint64(100),
421                                         BlockID:     bc.NewHash([32]byte{0x06, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
422                                         BlockHeight: uint64(100),
423                                         Position:    uint32(100),
424                                 },
425                                 &query.AnnotatedTx{
426                                         ID:          bc.NewHash([32]byte{0x07, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
427                                         Timestamp:   uint64(100),
428                                         BlockID:     bc.NewHash([32]byte{0x07, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
429                                         BlockHeight: uint64(100),
430                                         Position:    uint32(100),
431                                 },
432                                 &query.AnnotatedTx{
433                                         ID:          bc.NewHash([32]byte{0x08, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
434                                         Timestamp:   uint64(100),
435                                         BlockID:     bc.NewHash([32]byte{0x08, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
436                                         BlockHeight: uint64(100),
437                                         Position:    uint32(100),
438                                 },
439                         },
440                 },
441         }
442
443         for i, c := range cases {
444                 testDB := dbm.NewDB("testdb", "leveldb", "temp")
445                 walletStore := NewWalletStore(testDB)
446                 ws := walletStore.InitBatch()
447                 for _, tx := range c.txs {
448                         if err := ws.SetUnconfirmedTransaction(tx.ID.String(), tx); err != nil {
449                                 t.Fatal(err)
450                         }
451                 }
452
453                 if err := ws.CommitBatch(); err != nil {
454                         t.Fatal(err)
455                 }
456
457                 gotTxs, err := ws.ListUnconfirmedTransactions()
458                 if err != nil {
459                         t.Fatal(err)
460                 }
461
462                 sort.Sort(SortUnconfirmedTxs(gotTxs))
463                 sort.Sort(SortUnconfirmedTxs(c.txs))
464
465                 if !testutil.DeepEqual(gotTxs, c.txs) {
466                         t.Errorf("case %v: list unconfirmed transactions, got: %v, want: %v.", i, gotTxs, c.txs)
467                 }
468
469                 testDB.Close()
470                 os.RemoveAll("temp")
471         }
472 }
473
474 type SortUnconfirmedTxs []*query.AnnotatedTx
475
476 func (s SortUnconfirmedTxs) Len() int { return len(s) }
477 func (s SortUnconfirmedTxs) Less(i, j int) bool {
478         return bytes.Compare(s[i].ID.Bytes(), s[j].ID.Bytes()) < 0
479 }
480 func (s SortUnconfirmedTxs) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
481
482 func TestGetGlobalTransactionIndex(t *testing.T) {
483         cases := []struct {
484                 globalTxID string
485                 blockHash  bc.Hash
486                 position   uint64
487         }{
488                 {
489                         globalTxID: "",
490                         blockHash:  bc.NewHash([32]byte{}),
491                         position:   uint64(0),
492                 },
493                 {
494                         globalTxID: "8838474e18e945e2f648745a362ac6988bad172b0eef5c593038a2fc8b46261e",
495                         blockHash:  bc.NewHash([32]byte{0x00, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
496                         position:   uint64(0),
497                 },
498                 {
499                         globalTxID: "d8de517917a591daa447d6be28ffb2fac866703e4feb65e86221be9a22d3033a",
500                         blockHash:  bc.NewHash([32]byte{0x00, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
501                         position:   uint64(99),
502                 },
503                 {
504                         globalTxID: "f4c64e9f72623c26b06e17f909aec7c03c927fcf681781489257097e537b8d5a",
505                         blockHash:  bc.NewHash([32]byte{0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
506                         position:   uint64(99),
507                 },
508         }
509
510         for i, c := range cases {
511                 testDB := dbm.NewDB("testdb", "leveldb", "temp")
512                 walletStore := NewWalletStore(testDB)
513                 ws := walletStore.InitBatch()
514                 ws.SetGlobalTransactionIndex(c.globalTxID, &c.blockHash, c.position)
515
516                 if err := ws.CommitBatch(); err != nil {
517                         t.Fatal(err)
518                 }
519
520                 gotIndex := ws.GetGlobalTransactionIndex(c.globalTxID)
521                 wantIndex := CalcGlobalTxIndex(&c.blockHash, c.position)
522
523                 if !testutil.DeepEqual(gotIndex, wantIndex) {
524                         t.Errorf("case %v: got global transaction index, got: %v, want: %v.", i, gotIndex, wantIndex)
525                 }
526
527                 testDB.Close()
528                 os.RemoveAll("temp")
529         }
530 }
531
532 func TestGetAsset(t *testing.T) {
533         cases := []struct {
534                 asset *asset.Asset
535         }{
536                 {
537                         asset: &asset.Asset{
538                                 AssetID:       bc.NewAssetID([32]byte{}),
539                                 DefinitionMap: map[string]interface{}{},
540                         },
541                 },
542                 {
543                         asset: &asset.Asset{
544                                 AssetID:       bc.NewAssetID([32]byte{0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
545                                 DefinitionMap: map[string]interface{}{},
546                         },
547                 },
548                 {
549                         asset: &asset.Asset{
550                                 AssetID: bc.NewAssetID([32]byte{}),
551                                 DefinitionMap: map[string]interface{}{
552                                         "Name": "assetname",
553                                 },
554                         },
555                 },
556                 {
557                         asset: &asset.Asset{
558                                 AssetID: bc.NewAssetID([32]byte{0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
559                                 DefinitionMap: map[string]interface{}{
560                                         "Name": "assetname",
561                                 },
562                         },
563                 },
564                 {
565                         asset: &asset.Asset{
566                                 AssetID: bc.NewAssetID([32]byte{0x02, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
567                                 DefinitionMap: map[string]interface{}{
568                                         "Name":   "assetname",
569                                         "Amount": "1000000",
570                                 },
571                         },
572                 },
573         }
574
575         for i, c := range cases {
576                 testDB := dbm.NewDB("testdb", "leveldb", "temp")
577                 walletStore := NewWalletStore(testDB)
578                 ws := walletStore.InitBatch()
579                 definitionByte, err := json.Marshal(c.asset.DefinitionMap)
580                 if err != nil {
581                         t.Fatal(err)
582                 }
583
584                 ws.SetAssetDefinition(&c.asset.AssetID, definitionByte)
585                 if err := ws.CommitBatch(); err != nil {
586                         t.Fatal(err)
587                 }
588
589                 gotAsset, err := ws.GetAsset(&c.asset.AssetID)
590                 if err != nil {
591                         t.Fatal(err)
592                 }
593
594                 if !testutil.DeepEqual(gotAsset.DefinitionMap, c.asset.DefinitionMap) {
595                         t.Errorf("case %v: got asset, got: %v, want: %v.", i, gotAsset.DefinitionMap, c.asset.DefinitionMap)
596                 }
597
598                 testDB.Close()
599                 os.RemoveAll("temp")
600         }
601 }
602
603 func TestDeleteTransactions(t *testing.T) {
604         cases := []struct {
605                 height uint64
606                 txs    []*query.AnnotatedTx
607         }{
608                 {
609                         height: uint64(0),
610                         txs:    []*query.AnnotatedTx{},
611                 },
612                 {
613                         height: uint64(0),
614                         txs: []*query.AnnotatedTx{
615                                 &query.AnnotatedTx{
616                                         ID:          bc.NewHash([32]byte{0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
617                                         Timestamp:   uint64(9988000),
618                                         BlockHeight: uint64(0),
619                                         Position:    uint32(2333),
620                                 },
621                         },
622                 },
623                 {
624                         height: uint64(1000000),
625                         txs: []*query.AnnotatedTx{
626                                 &query.AnnotatedTx{
627                                         ID:          bc.NewHash([32]byte{0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
628                                         Timestamp:   uint64(9988000),
629                                         BlockHeight: uint64(1000000),
630                                         Position:    uint32(0),
631                                 },
632                                 &query.AnnotatedTx{
633                                         ID:          bc.NewHash([32]byte{0x02, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
634                                         Timestamp:   uint64(9988000),
635                                         BlockHeight: uint64(1000000),
636                                         Position:    uint32(1),
637                                 },
638                                 &query.AnnotatedTx{
639                                         ID:          bc.NewHash([32]byte{0x03, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
640                                         Timestamp:   uint64(9988000),
641                                         BlockHeight: uint64(1000000),
642                                         Position:    uint32(2),
643                                 },
644                                 &query.AnnotatedTx{
645                                         ID:          bc.NewHash([32]byte{0x04, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
646                                         Timestamp:   uint64(9988000),
647                                         BlockHeight: uint64(1000000),
648                                         Position:    uint32(3),
649                                 },
650                                 &query.AnnotatedTx{
651                                         ID:          bc.NewHash([32]byte{0x05, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
652                                         Timestamp:   uint64(9988000),
653                                         BlockHeight: uint64(1000000),
654                                         Position:    uint32(4),
655                                 },
656                                 &query.AnnotatedTx{
657                                         ID:          bc.NewHash([32]byte{0x06, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
658                                         Timestamp:   uint64(9988000),
659                                         BlockHeight: uint64(1000000),
660                                         Position:    uint32(5),
661                                 },
662                                 &query.AnnotatedTx{
663                                         ID:          bc.NewHash([32]byte{0x07, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
664                                         Timestamp:   uint64(9988000),
665                                         BlockHeight: uint64(1000000),
666                                         Position:    uint32(6),
667                                 },
668                                 &query.AnnotatedTx{
669                                         ID:          bc.NewHash([32]byte{0x08, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
670                                         Timestamp:   uint64(9988000),
671                                         BlockHeight: uint64(1000000),
672                                         Position:    uint32(7),
673                                 },
674                                 &query.AnnotatedTx{
675                                         ID:          bc.NewHash([32]byte{0x09, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
676                                         Timestamp:   uint64(9988000),
677                                         BlockHeight: uint64(1000000),
678                                         Position:    uint32(8),
679                                 },
680                                 &query.AnnotatedTx{
681                                         ID:          bc.NewHash([32]byte{0x0a, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
682                                         Timestamp:   uint64(9988000),
683                                         BlockHeight: uint64(1000000),
684                                         Position:    uint32(9),
685                                 },
686                         },
687                 },
688         }
689
690         for i, c := range cases {
691                 testDB := dbm.NewDB("testdb", "leveldb", "temp")
692                 walletStore := NewWalletStore(testDB)
693                 ws := walletStore.InitBatch()
694                 // store txs by given height
695                 for _, tx := range c.txs {
696                         if err := ws.SetTransaction(c.height, tx); err != nil {
697                                 t.Fatal(err)
698                         }
699                 }
700
701                 if err := ws.CommitBatch(); err != nil {
702                         t.Fatal(err)
703                 }
704
705                 // get tx by txID
706                 for j := 0; j < len(c.txs); j++ {
707                         gotTx, err := ws.GetTransaction(c.txs[j].ID.String())
708                         if err != nil {
709                                 t.Fatal(err)
710                         }
711
712                         if !testutil.DeepEqual(gotTx, c.txs[j]) {
713                                 t.Errorf("case %v: got transaction, got: %v, want: %v.", i, gotTx, c.txs[j])
714                         }
715                 }
716
717                 // delete all txs by given height
718                 ws = walletStore.InitBatch()
719                 ws.DeleteTransactions(c.height)
720                 if err := ws.CommitBatch(); err != nil {
721                         t.Fatal(err)
722                 }
723
724                 // get tx by txID, it should return err
725                 for _, tx := range c.txs {
726                         _, err := ws.GetTransaction(tx.ID.String())
727                         if err == nil {
728                                 t.Errorf("case: %v: it should return some err.", i)
729                         }
730                 }
731
732                 testDB.Close()
733                 os.RemoveAll("temp")
734         }
735 }
736
737 func TestDeleteWalletTransactions(t *testing.T) {
738         cases := []struct {
739                 height uint64
740                 txs    []*query.AnnotatedTx
741         }{
742                 {
743                         height: uint64(0),
744                         txs:    []*query.AnnotatedTx{},
745                 },
746                 {
747                         height: uint64(0),
748                         txs: []*query.AnnotatedTx{
749                                 &query.AnnotatedTx{
750                                         ID:          bc.NewHash([32]byte{0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
751                                         Timestamp:   uint64(9988000),
752                                         BlockHeight: uint64(0),
753                                         Position:    uint32(2333),
754                                 },
755                         },
756                 },
757                 {
758                         height: uint64(1000000),
759                         txs: []*query.AnnotatedTx{
760                                 &query.AnnotatedTx{
761                                         ID:          bc.NewHash([32]byte{0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
762                                         Timestamp:   uint64(9988000),
763                                         BlockHeight: uint64(1000000),
764                                         Position:    uint32(0),
765                                 },
766                                 &query.AnnotatedTx{
767                                         ID:          bc.NewHash([32]byte{0x02, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
768                                         Timestamp:   uint64(9988000),
769                                         BlockHeight: uint64(1000000),
770                                         Position:    uint32(1),
771                                 },
772                                 &query.AnnotatedTx{
773                                         ID:          bc.NewHash([32]byte{0x03, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
774                                         Timestamp:   uint64(9988000),
775                                         BlockHeight: uint64(1000000),
776                                         Position:    uint32(2),
777                                 },
778                                 &query.AnnotatedTx{
779                                         ID:          bc.NewHash([32]byte{0x04, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
780                                         Timestamp:   uint64(9988000),
781                                         BlockHeight: uint64(1000000),
782                                         Position:    uint32(3),
783                                 },
784                                 &query.AnnotatedTx{
785                                         ID:          bc.NewHash([32]byte{0x05, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
786                                         Timestamp:   uint64(9988000),
787                                         BlockHeight: uint64(1000000),
788                                         Position:    uint32(4),
789                                 },
790                                 &query.AnnotatedTx{
791                                         ID:          bc.NewHash([32]byte{0x06, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
792                                         Timestamp:   uint64(9988000),
793                                         BlockHeight: uint64(1000000),
794                                         Position:    uint32(5),
795                                 },
796                                 &query.AnnotatedTx{
797                                         ID:          bc.NewHash([32]byte{0x07, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
798                                         Timestamp:   uint64(9988000),
799                                         BlockHeight: uint64(1000000),
800                                         Position:    uint32(6),
801                                 },
802                                 &query.AnnotatedTx{
803                                         ID:          bc.NewHash([32]byte{0x08, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
804                                         Timestamp:   uint64(9988000),
805                                         BlockHeight: uint64(1000000),
806                                         Position:    uint32(7),
807                                 },
808                                 &query.AnnotatedTx{
809                                         ID:          bc.NewHash([32]byte{0x09, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
810                                         Timestamp:   uint64(9988000),
811                                         BlockHeight: uint64(1000000),
812                                         Position:    uint32(8),
813                                 },
814                                 &query.AnnotatedTx{
815                                         ID:          bc.NewHash([32]byte{0x0a, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
816                                         Timestamp:   uint64(9988000),
817                                         BlockHeight: uint64(1000000),
818                                         Position:    uint32(9),
819                                 },
820                         },
821                 },
822         }
823
824         for i, c := range cases {
825                 testDB := dbm.NewDB("testdb", "leveldb", "temp")
826                 walletStore := NewWalletStore(testDB)
827                 ws := walletStore.InitBatch()
828                 // store txs by given height
829                 for _, tx := range c.txs {
830                         if err := ws.SetTransaction(c.height, tx); err != nil {
831                                 t.Fatal(err)
832                         }
833                 }
834
835                 if err := ws.CommitBatch(); err != nil {
836                         t.Fatal(err)
837                 }
838
839                 // delete all txs
840                 ws = walletStore.InitBatch()
841                 ws.DeleteWalletTransactions()
842                 if err := ws.CommitBatch(); err != nil {
843                         t.Fatal(err)
844                 }
845
846                 // get tx by txID, it should return err
847                 for _, tx := range c.txs {
848                         _, err := ws.GetTransaction(tx.ID.String())
849                         if err == nil {
850                                 t.Errorf("case: %v: it should return some err.", i)
851                         }
852                 }
853
854                 testDB.Close()
855                 os.RemoveAll("temp")
856         }
857 }
858
859 func TestDeleteWalletUTXOs(t *testing.T) {
860         cases := []struct {
861                 utxos []*acc.UTXO
862         }{
863                 {
864                         utxos: []*acc.UTXO{},
865                 },
866                 {
867                         utxos: []*acc.UTXO{
868                                 &acc.UTXO{
869                                         OutputID:  bc.NewHash([32]byte{}),
870                                         Address:   "address0",
871                                         Amount:    uint64(0),
872                                         Change:    true,
873                                         AccountID: "account",
874                                         SourcePos: uint64(0),
875                                 },
876                         },
877                 },
878                 {
879                         utxos: []*acc.UTXO{
880                                 &acc.UTXO{
881                                         OutputID:  bc.NewHash([32]byte{0x08, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
882                                         Address:   "address0",
883                                         Amount:    uint64(0),
884                                         Change:    true,
885                                         AccountID: "account",
886                                         SourcePos: uint64(0),
887                                 },
888                         },
889                 },
890                 {
891                         utxos: []*acc.UTXO{
892                                 &acc.UTXO{
893                                         OutputID:  bc.NewHash([32]byte{0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
894                                         Address:   "address0",
895                                         Amount:    uint64(0),
896                                         Change:    true,
897                                         AccountID: "account",
898                                         SourcePos: uint64(0),
899                                 },
900                                 &acc.UTXO{
901                                         OutputID:  bc.NewHash([32]byte{0x02, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
902                                         Address:   "address1",
903                                         Amount:    uint64(0),
904                                         Change:    true,
905                                         AccountID: "account",
906                                         SourcePos: uint64(0),
907                                 },
908                                 &acc.UTXO{
909                                         OutputID:  bc.NewHash([32]byte{0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
910                                         Address:   "address2",
911                                         Amount:    uint64(0),
912                                         Change:    true,
913                                         AccountID: "account",
914                                         SourcePos: uint64(0),
915                                 },
916                                 &acc.UTXO{
917                                         OutputID:  bc.NewHash([32]byte{0x04, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
918                                         Address:   "address3",
919                                         Amount:    uint64(0),
920                                         Change:    true,
921                                         AccountID: "account",
922                                         SourcePos: uint64(0),
923                                 },
924                                 &acc.UTXO{
925                                         OutputID:  bc.NewHash([32]byte{0x05, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
926                                         Address:   "address4",
927                                         Amount:    uint64(0),
928                                         Change:    true,
929                                         AccountID: "account",
930                                         SourcePos: uint64(0),
931                                 },
932                                 &acc.UTXO{
933                                         OutputID:  bc.NewHash([32]byte{0x06, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
934                                         Address:   "address5",
935                                         Amount:    uint64(0),
936                                         Change:    true,
937                                         AccountID: "account",
938                                         SourcePos: uint64(0),
939                                 },
940                                 &acc.UTXO{
941                                         OutputID:  bc.NewHash([32]byte{0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
942                                         Address:   "address6",
943                                         Amount:    uint64(0),
944                                         Change:    true,
945                                         AccountID: "account",
946                                         SourcePos: uint64(0),
947                                 },
948                                 &acc.UTXO{
949                                         OutputID:  bc.NewHash([32]byte{0x08, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
950                                         Address:   "address7",
951                                         Amount:    uint64(0),
952                                         Change:    true,
953                                         AccountID: "account",
954                                         SourcePos: uint64(0),
955                                 },
956                                 &acc.UTXO{
957                                         OutputID:  bc.NewHash([32]byte{0x09, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
958                                         Address:   "address8",
959                                         Amount:    uint64(0),
960                                         Change:    true,
961                                         AccountID: "account",
962                                         SourcePos: uint64(0),
963                                 },
964                                 &acc.UTXO{
965                                         OutputID:  bc.NewHash([32]byte{0x0a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
966                                         Address:   "address9",
967                                         Amount:    uint64(0),
968                                         Change:    true,
969                                         AccountID: "account",
970                                         SourcePos: uint64(0),
971                                 },
972                         },
973                 },
974         }
975
976         for i, c := range cases {
977                 testDB := dbm.NewDB("testdb", "leveldb", "temp")
978                 walletStore := NewWalletStore(testDB)
979                 ws := walletStore.InitBatch()
980                 // store utxos
981                 for _, utxo := range c.utxos {
982                         if err := ws.SetContractUTXO(utxo.OutputID, utxo); err != nil {
983                                 t.Fatal(err)
984                         }
985                 }
986
987                 if err := ws.CommitBatch(); err != nil {
988                         t.Fatal(err)
989                 }
990
991                 // delete all utxos
992                 ws = walletStore.InitBatch()
993                 ws.DeleteWalletUTXOs()
994                 if err := ws.CommitBatch(); err != nil {
995                         t.Fatal(err)
996                 }
997
998                 // get utxo by outputID, it should return err
999                 accountStore := NewAccountStore(testDB)
1000                 for _, utxo := range c.utxos {
1001                         _, err := accountStore.GetUTXO(utxo.OutputID)
1002                         if err == nil {
1003                                 t.Errorf("case: %v: it should return some err.", i)
1004                         }
1005                 }
1006
1007                 testDB.Close()
1008                 os.RemoveAll("temp")
1009         }
1010 }
1011
1012 func TestGetStandardUTXO(t *testing.T) {
1013         cases := []struct {
1014                 utxos []*acc.UTXO
1015         }{
1016                 {
1017                         utxos: []*acc.UTXO{},
1018                 },
1019                 {
1020                         utxos: []*acc.UTXO{
1021                                 &acc.UTXO{
1022                                         OutputID:  bc.NewHash([32]byte{}),
1023                                         Address:   "address0",
1024                                         Amount:    uint64(0),
1025                                         Change:    true,
1026                                         AccountID: "account",
1027                                         SourcePos: uint64(0),
1028                                 },
1029                         },
1030                 },
1031                 {
1032                         utxos: []*acc.UTXO{
1033                                 &acc.UTXO{
1034                                         OutputID:  bc.NewHash([32]byte{0x08, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1035                                         Address:   "address0",
1036                                         Amount:    uint64(0),
1037                                         Change:    true,
1038                                         AccountID: "account",
1039                                         SourcePos: uint64(0),
1040                                 },
1041                         },
1042                 },
1043                 {
1044                         utxos: []*acc.UTXO{
1045                                 &acc.UTXO{
1046                                         OutputID:  bc.NewHash([32]byte{0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1047                                         Address:   "address0",
1048                                         Amount:    uint64(0),
1049                                         Change:    true,
1050                                         AccountID: "account",
1051                                         SourcePos: uint64(0),
1052                                 },
1053                                 &acc.UTXO{
1054                                         OutputID:  bc.NewHash([32]byte{0x02, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1055                                         Address:   "address1",
1056                                         Amount:    uint64(0),
1057                                         Change:    true,
1058                                         AccountID: "account",
1059                                         SourcePos: uint64(0),
1060                                 },
1061                                 &acc.UTXO{
1062                                         OutputID:  bc.NewHash([32]byte{0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1063                                         Address:   "address2",
1064                                         Amount:    uint64(0),
1065                                         Change:    true,
1066                                         AccountID: "account",
1067                                         SourcePos: uint64(0),
1068                                 },
1069                                 &acc.UTXO{
1070                                         OutputID:  bc.NewHash([32]byte{0x04, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1071                                         Address:   "address3",
1072                                         Amount:    uint64(0),
1073                                         Change:    true,
1074                                         AccountID: "account",
1075                                         SourcePos: uint64(0),
1076                                 },
1077                                 &acc.UTXO{
1078                                         OutputID:  bc.NewHash([32]byte{0x05, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1079                                         Address:   "address4",
1080                                         Amount:    uint64(0),
1081                                         Change:    true,
1082                                         AccountID: "account",
1083                                         SourcePos: uint64(0),
1084                                 },
1085                                 &acc.UTXO{
1086                                         OutputID:  bc.NewHash([32]byte{0x06, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1087                                         Address:   "address5",
1088                                         Amount:    uint64(0),
1089                                         Change:    true,
1090                                         AccountID: "account",
1091                                         SourcePos: uint64(0),
1092                                 },
1093                                 &acc.UTXO{
1094                                         OutputID:  bc.NewHash([32]byte{0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1095                                         Address:   "address6",
1096                                         Amount:    uint64(0),
1097                                         Change:    true,
1098                                         AccountID: "account",
1099                                         SourcePos: uint64(0),
1100                                 },
1101                                 &acc.UTXO{
1102                                         OutputID:  bc.NewHash([32]byte{0x08, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1103                                         Address:   "address7",
1104                                         Amount:    uint64(0),
1105                                         Change:    true,
1106                                         AccountID: "account",
1107                                         SourcePos: uint64(0),
1108                                 },
1109                                 &acc.UTXO{
1110                                         OutputID:  bc.NewHash([32]byte{0x09, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1111                                         Address:   "address8",
1112                                         Amount:    uint64(0),
1113                                         Change:    true,
1114                                         AccountID: "account",
1115                                         SourcePos: uint64(0),
1116                                 },
1117                                 &acc.UTXO{
1118                                         OutputID:  bc.NewHash([32]byte{0x0a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1119                                         Address:   "address9",
1120                                         Amount:    uint64(0),
1121                                         Change:    true,
1122                                         AccountID: "account",
1123                                         SourcePos: uint64(0),
1124                                 },
1125                         },
1126                 },
1127         }
1128
1129         for i, c := range cases {
1130                 testDB := dbm.NewDB("testdb", "leveldb", "temp")
1131                 accountStore := NewAccountStore(testDB)
1132                 as := accountStore.InitBatch()
1133                 // store utxos
1134                 for _, utxo := range c.utxos {
1135                         if err := as.SetStandardUTXO(utxo.OutputID, utxo); err != nil {
1136                                 t.Fatal(err)
1137                         }
1138                 }
1139
1140                 if err := as.CommitBatch(); err != nil {
1141                         t.Fatal(err)
1142                 }
1143
1144                 // get utxo by outputID
1145                 walletStore := NewWalletStore(testDB)
1146                 for _, utxo := range c.utxos {
1147                         gotUTXO, err := walletStore.GetStandardUTXO(utxo.OutputID)
1148                         if err != nil {
1149                                 t.Fatal(err)
1150                         }
1151
1152                         if !testutil.DeepEqual(gotUTXO, utxo) {
1153                                 t.Errorf("case %v: got standard utxo, got: %v, want: %v.", i, gotUTXO, utxo)
1154                         }
1155                 }
1156
1157                 testDB.Close()
1158                 os.RemoveAll("temp")
1159         }
1160 }
1161
1162 func TestListAccountUTXOs(t *testing.T) {
1163         cases := []struct {
1164                 standardUTXOs   []*acc.UTXO
1165                 contractUTXOs   []*acc.UTXO
1166                 id              string
1167                 isSmartContract bool
1168                 want            []*acc.UTXO
1169         }{
1170                 {
1171                         standardUTXOs:   []*acc.UTXO{},
1172                         contractUTXOs:   []*acc.UTXO{},
1173                         id:              "",
1174                         isSmartContract: false,
1175                         want:            []*acc.UTXO{},
1176                 },
1177                 {
1178                         standardUTXOs: []*acc.UTXO{
1179                                 &acc.UTXO{
1180                                         OutputID:  bc.NewHash([32]byte{0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1181                                         Address:   "address0",
1182                                         Amount:    uint64(0),
1183                                         Change:    true,
1184                                         AccountID: "account",
1185                                         SourcePos: uint64(0),
1186                                 },
1187                                 &acc.UTXO{
1188                                         OutputID:  bc.NewHash([32]byte{0x01, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1189                                         Address:   "address0",
1190                                         Amount:    uint64(0),
1191                                         Change:    true,
1192                                         AccountID: "account",
1193                                         SourcePos: uint64(0),
1194                                 },
1195                         },
1196                         contractUTXOs:   []*acc.UTXO{},
1197                         id:              "01f3",
1198                         isSmartContract: false,
1199                         want:            []*acc.UTXO{},
1200                 },
1201                 {
1202                         standardUTXOs: []*acc.UTXO{
1203                                 &acc.UTXO{
1204                                         OutputID:  bc.NewHash([32]byte{0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1205                                         Address:   "address0",
1206                                         Amount:    uint64(0),
1207                                         Change:    true,
1208                                         AccountID: "account",
1209                                         SourcePos: uint64(0),
1210                                 },
1211                                 &acc.UTXO{
1212                                         OutputID:  bc.NewHash([32]byte{0x01, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1213                                         Address:   "address0",
1214                                         Amount:    uint64(0),
1215                                         Change:    true,
1216                                         AccountID: "account",
1217                                         SourcePos: uint64(0),
1218                                 },
1219                         },
1220                         contractUTXOs: []*acc.UTXO{
1221                                 &acc.UTXO{
1222                                         OutputID:  bc.NewHash([32]byte{0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1223                                         Address:   "address0",
1224                                         Amount:    uint64(0),
1225                                         Change:    true,
1226                                         AccountID: "account",
1227                                         SourcePos: uint64(0),
1228                                 },
1229                                 &acc.UTXO{
1230                                         OutputID:  bc.NewHash([32]byte{0x04, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1231                                         Address:   "address0",
1232                                         Amount:    uint64(0),
1233                                         Change:    true,
1234                                         AccountID: "account",
1235                                         SourcePos: uint64(0),
1236                                 },
1237                         },
1238                         id:              "01f3",
1239                         isSmartContract: true,
1240                         want:            []*acc.UTXO{},
1241                 },
1242                 {
1243                         standardUTXOs: []*acc.UTXO{
1244                                 &acc.UTXO{
1245                                         OutputID:  bc.NewHash([32]byte{0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1246                                         Address:   "address0",
1247                                         Amount:    uint64(0),
1248                                         Change:    true,
1249                                         AccountID: "account",
1250                                         SourcePos: uint64(0),
1251                                 },
1252                                 &acc.UTXO{
1253                                         OutputID:  bc.NewHash([32]byte{0x02, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1254                                         Address:   "address0",
1255                                         Amount:    uint64(0),
1256                                         Change:    true,
1257                                         AccountID: "account",
1258                                         SourcePos: uint64(0),
1259                                 },
1260                         },
1261                         contractUTXOs: []*acc.UTXO{
1262                                 &acc.UTXO{
1263                                         OutputID:  bc.NewHash([32]byte{0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1264                                         Address:   "address0",
1265                                         Amount:    uint64(0),
1266                                         Change:    true,
1267                                         AccountID: "account",
1268                                         SourcePos: uint64(0),
1269                                 },
1270                                 &acc.UTXO{
1271                                         OutputID:  bc.NewHash([32]byte{0x04, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1272                                         Address:   "address0",
1273                                         Amount:    uint64(0),
1274                                         Change:    true,
1275                                         AccountID: "account",
1276                                         SourcePos: uint64(0),
1277                                 },
1278                         },
1279                         id:              "",
1280                         isSmartContract: false,
1281                         want: []*acc.UTXO{
1282                                 &acc.UTXO{
1283                                         OutputID:  bc.NewHash([32]byte{0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1284                                         Address:   "address0",
1285                                         Amount:    uint64(0),
1286                                         Change:    true,
1287                                         AccountID: "account",
1288                                         SourcePos: uint64(0),
1289                                 },
1290                                 &acc.UTXO{
1291                                         OutputID:  bc.NewHash([32]byte{0x02, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1292                                         Address:   "address0",
1293                                         Amount:    uint64(0),
1294                                         Change:    true,
1295                                         AccountID: "account",
1296                                         SourcePos: uint64(0),
1297                                 },
1298                         },
1299                 },
1300                 {
1301                         standardUTXOs: []*acc.UTXO{
1302                                 &acc.UTXO{
1303                                         OutputID:  bc.NewHash([32]byte{0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1304                                         Address:   "address0",
1305                                         Amount:    uint64(0),
1306                                         Change:    true,
1307                                         AccountID: "account",
1308                                         SourcePos: uint64(0),
1309                                 },
1310                                 &acc.UTXO{
1311                                         OutputID:  bc.NewHash([32]byte{0x02, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1312                                         Address:   "address0",
1313                                         Amount:    uint64(0),
1314                                         Change:    true,
1315                                         AccountID: "account",
1316                                         SourcePos: uint64(0),
1317                                 },
1318                         },
1319                         contractUTXOs: []*acc.UTXO{
1320                                 &acc.UTXO{
1321                                         OutputID:  bc.NewHash([32]byte{0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1322                                         Address:   "address0",
1323                                         Amount:    uint64(0),
1324                                         Change:    true,
1325                                         AccountID: "account",
1326                                         SourcePos: uint64(0),
1327                                 },
1328                                 &acc.UTXO{
1329                                         OutputID:  bc.NewHash([32]byte{0x04, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1330                                         Address:   "address0",
1331                                         Amount:    uint64(0),
1332                                         Change:    true,
1333                                         AccountID: "account",
1334                                         SourcePos: uint64(0),
1335                                 },
1336                         },
1337                         id:              "02",
1338                         isSmartContract: false,
1339                         want: []*acc.UTXO{
1340                                 &acc.UTXO{
1341                                         OutputID:  bc.NewHash([32]byte{0x02, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1342                                         Address:   "address0",
1343                                         Amount:    uint64(0),
1344                                         Change:    true,
1345                                         AccountID: "account",
1346                                         SourcePos: uint64(0),
1347                                 },
1348                         },
1349                 },
1350                 {
1351                         standardUTXOs: []*acc.UTXO{
1352                                 &acc.UTXO{
1353                                         OutputID:  bc.NewHash([32]byte{0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1354                                         Address:   "address0",
1355                                         Amount:    uint64(0),
1356                                         Change:    true,
1357                                         AccountID: "account",
1358                                         SourcePos: uint64(0),
1359                                 },
1360                                 &acc.UTXO{
1361                                         OutputID:  bc.NewHash([32]byte{0x01, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1362                                         Address:   "address0",
1363                                         Amount:    uint64(0),
1364                                         Change:    true,
1365                                         AccountID: "account",
1366                                         SourcePos: uint64(0),
1367                                 },
1368                         },
1369                         contractUTXOs: []*acc.UTXO{
1370                                 &acc.UTXO{
1371                                         OutputID:  bc.NewHash([32]byte{0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1372                                         Address:   "address0",
1373                                         Amount:    uint64(0),
1374                                         Change:    true,
1375                                         AccountID: "account",
1376                                         SourcePos: uint64(0),
1377                                 },
1378                                 &acc.UTXO{
1379                                         OutputID:  bc.NewHash([32]byte{0x04, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1380                                         Address:   "address0",
1381                                         Amount:    uint64(0),
1382                                         Change:    true,
1383                                         AccountID: "account",
1384                                         SourcePos: uint64(0),
1385                                 },
1386                         },
1387                         id:              "",
1388                         isSmartContract: true,
1389                         want: []*acc.UTXO{
1390                                 &acc.UTXO{
1391                                         OutputID:  bc.NewHash([32]byte{0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1392                                         Address:   "address0",
1393                                         Amount:    uint64(0),
1394                                         Change:    true,
1395                                         AccountID: "account",
1396                                         SourcePos: uint64(0),
1397                                 },
1398                                 &acc.UTXO{
1399                                         OutputID:  bc.NewHash([32]byte{0x04, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1400                                         Address:   "address0",
1401                                         Amount:    uint64(0),
1402                                         Change:    true,
1403                                         AccountID: "account",
1404                                         SourcePos: uint64(0),
1405                                 },
1406                         },
1407                 },
1408                 {
1409                         standardUTXOs: []*acc.UTXO{
1410                                 &acc.UTXO{
1411                                         OutputID:  bc.NewHash([32]byte{0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1412                                         Address:   "address0",
1413                                         Amount:    uint64(0),
1414                                         Change:    true,
1415                                         AccountID: "account",
1416                                         SourcePos: uint64(0),
1417                                 },
1418                                 &acc.UTXO{
1419                                         OutputID:  bc.NewHash([32]byte{0x01, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1420                                         Address:   "address0",
1421                                         Amount:    uint64(0),
1422                                         Change:    true,
1423                                         AccountID: "account",
1424                                         SourcePos: uint64(0),
1425                                 },
1426                         },
1427                         contractUTXOs: []*acc.UTXO{
1428                                 &acc.UTXO{
1429                                         OutputID:  bc.NewHash([32]byte{0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1430                                         Address:   "address0",
1431                                         Amount:    uint64(0),
1432                                         Change:    true,
1433                                         AccountID: "account",
1434                                         SourcePos: uint64(0),
1435                                 },
1436                                 &acc.UTXO{
1437                                         OutputID:  bc.NewHash([32]byte{0x04, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1438                                         Address:   "address0",
1439                                         Amount:    uint64(0),
1440                                         Change:    true,
1441                                         AccountID: "account",
1442                                         SourcePos: uint64(0),
1443                                 },
1444                         },
1445                         id:              "03",
1446                         isSmartContract: true,
1447                         want: []*acc.UTXO{
1448                                 &acc.UTXO{
1449                                         OutputID:  bc.NewHash([32]byte{0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1450                                         Address:   "address0",
1451                                         Amount:    uint64(0),
1452                                         Change:    true,
1453                                         AccountID: "account",
1454                                         SourcePos: uint64(0),
1455                                 },
1456                         },
1457                 },
1458         }
1459
1460         for i, c := range cases {
1461                 testDB := dbm.NewDB("testdb", "leveldb", "temp")
1462                 accountStore := NewAccountStore(testDB)
1463                 as := accountStore.InitBatch()
1464                 // store standard utxos
1465                 for _, utxo := range c.standardUTXOs {
1466                         if err := as.SetStandardUTXO(utxo.OutputID, utxo); err != nil {
1467                                 t.Fatal(err)
1468                         }
1469                 }
1470
1471                 if err := as.CommitBatch(); err != nil {
1472                         t.Fatal(err)
1473                 }
1474
1475                 // store contract utxos
1476                 walletStore := NewWalletStore(testDB)
1477                 ws := walletStore.InitBatch()
1478                 for _, utxo := range c.contractUTXOs {
1479                         if err := ws.SetContractUTXO(utxo.OutputID, utxo); err != nil {
1480                                 t.Fatal(err)
1481                         }
1482                 }
1483
1484                 if err := ws.CommitBatch(); err != nil {
1485                         t.Fatal(err)
1486                 }
1487
1488                 gotUTXOs, err := ws.ListAccountUTXOs(c.id, c.isSmartContract)
1489                 if err != nil {
1490                         t.Fatal(err)
1491                 }
1492
1493                 if !testutil.DeepEqual(gotUTXOs, c.want) {
1494                         t.Errorf("case %v: list account utxos, got: %v, want: %v.", i, gotUTXOs, c.want)
1495                 }
1496
1497                 testDB.Close()
1498                 os.RemoveAll("temp")
1499         }
1500 }
1501
1502 func TestListTransactions(t *testing.T) {
1503         cases := []struct {
1504                 unconfirmedTxs []*query.AnnotatedTx
1505                 confirmedTxs   []*query.AnnotatedTx
1506                 height         uint64
1507                 accountID      string
1508                 startTxID      string
1509                 count          uint
1510                 unconfirmed    bool
1511                 want           []*query.AnnotatedTx
1512         }{
1513                 {
1514                         unconfirmedTxs: []*query.AnnotatedTx{},
1515                         confirmedTxs:   []*query.AnnotatedTx{},
1516                         height:         uint64(0),
1517                         accountID:      "",
1518                         startTxID:      "",
1519                         count:          uint(0),
1520                         unconfirmed:    false,
1521                         want:           []*query.AnnotatedTx{},
1522                 },
1523                 {
1524                         unconfirmedTxs: []*query.AnnotatedTx{
1525                                 &query.AnnotatedTx{
1526                                         ID:          bc.NewHash([32]byte{0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1527                                         Timestamp:   uint64(100),
1528                                         BlockID:     bc.NewHash([32]byte{0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1529                                         BlockHeight: uint64(100),
1530                                         Position:    uint32(1),
1531                                         Inputs: []*query.AnnotatedInput{
1532                                                 &query.AnnotatedInput{
1533                                                         AccountID: "account1",
1534                                                 },
1535                                         },
1536                                 },
1537                                 &query.AnnotatedTx{
1538                                         ID:          bc.NewHash([32]byte{0x02, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1539                                         Timestamp:   uint64(100),
1540                                         BlockID:     bc.NewHash([32]byte{0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1541                                         BlockHeight: uint64(100),
1542                                         Position:    uint32(101),
1543                                         Inputs: []*query.AnnotatedInput{
1544                                                 &query.AnnotatedInput{
1545                                                         AccountID: "account1",
1546                                                 },
1547                                         },
1548                                 },
1549                         },
1550                         confirmedTxs: []*query.AnnotatedTx{
1551                                 &query.AnnotatedTx{
1552                                         ID:          bc.NewHash([32]byte{0x03, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1553                                         Timestamp:   uint64(100),
1554                                         BlockID:     bc.NewHash([32]byte{0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1555                                         BlockHeight: uint64(100),
1556                                         Position:    uint32(102),
1557                                         Inputs: []*query.AnnotatedInput{
1558                                                 &query.AnnotatedInput{
1559                                                         AccountID: "account1",
1560                                                 },
1561                                         },
1562                                 },
1563                                 &query.AnnotatedTx{
1564                                         ID:          bc.NewHash([32]byte{0x04, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1565                                         Timestamp:   uint64(100),
1566                                         BlockID:     bc.NewHash([32]byte{0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1567                                         BlockHeight: uint64(100),
1568                                         Position:    uint32(103),
1569                                         Inputs: []*query.AnnotatedInput{
1570                                                 &query.AnnotatedInput{
1571                                                         AccountID: "account1",
1572                                                 },
1573                                         },
1574                                 },
1575                         },
1576                         height:      uint64(100),
1577                         accountID:   "",
1578                         startTxID:   "",
1579                         count:       uint(0),
1580                         unconfirmed: false,
1581                         want:        []*query.AnnotatedTx{},
1582                 },
1583                 {
1584                         unconfirmedTxs: []*query.AnnotatedTx{
1585                                 &query.AnnotatedTx{
1586                                         ID:          bc.NewHash([32]byte{0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1587                                         Timestamp:   uint64(100),
1588                                         BlockID:     bc.NewHash([32]byte{0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1589                                         BlockHeight: uint64(100),
1590                                         Position:    uint32(101),
1591                                         Inputs: []*query.AnnotatedInput{
1592                                                 &query.AnnotatedInput{
1593                                                         AccountID: "account1",
1594                                                 },
1595                                         },
1596                                 },
1597                                 &query.AnnotatedTx{
1598                                         ID:          bc.NewHash([32]byte{0x02, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1599                                         Timestamp:   uint64(100),
1600                                         BlockID:     bc.NewHash([32]byte{0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1601                                         BlockHeight: uint64(100),
1602                                         Position:    uint32(120),
1603                                         Inputs: []*query.AnnotatedInput{
1604                                                 &query.AnnotatedInput{
1605                                                         AccountID: "account1",
1606                                                 },
1607                                         },
1608                                 },
1609                         },
1610                         confirmedTxs: []*query.AnnotatedTx{
1611                                 &query.AnnotatedTx{
1612                                         ID:          bc.NewHash([32]byte{0x03, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1613                                         Timestamp:   uint64(100),
1614                                         BlockID:     bc.NewHash([32]byte{0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1615                                         BlockHeight: uint64(100),
1616                                         Position:    uint32(130),
1617                                         Inputs: []*query.AnnotatedInput{
1618                                                 &query.AnnotatedInput{
1619                                                         AccountID: "account1",
1620                                                 },
1621                                         },
1622                                 },
1623                                 &query.AnnotatedTx{
1624                                         ID:          bc.NewHash([32]byte{0x04, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1625                                         Timestamp:   uint64(100),
1626                                         BlockID:     bc.NewHash([32]byte{0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1627                                         BlockHeight: uint64(100),
1628                                         Position:    uint32(140),
1629                                         Inputs: []*query.AnnotatedInput{
1630                                                 &query.AnnotatedInput{
1631                                                         AccountID: "account1",
1632                                                 },
1633                                         },
1634                                 },
1635                         },
1636                         height:      uint64(100),
1637                         accountID:   "",
1638                         startTxID:   "",
1639                         count:       uint(2),
1640                         unconfirmed: false,
1641                         want: []*query.AnnotatedTx{
1642                                 &query.AnnotatedTx{
1643                                         ID:          bc.NewHash([32]byte{0x03, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1644                                         Timestamp:   uint64(100),
1645                                         BlockID:     bc.NewHash([32]byte{0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1646                                         BlockHeight: uint64(100),
1647                                         Position:    uint32(130),
1648                                         Inputs: []*query.AnnotatedInput{
1649                                                 &query.AnnotatedInput{
1650                                                         AccountID: "account1",
1651                                                 },
1652                                         },
1653                                 },
1654                                 &query.AnnotatedTx{
1655                                         ID:          bc.NewHash([32]byte{0x04, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1656                                         Timestamp:   uint64(100),
1657                                         BlockID:     bc.NewHash([32]byte{0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1658                                         BlockHeight: uint64(100),
1659                                         Position:    uint32(140),
1660                                         Inputs: []*query.AnnotatedInput{
1661                                                 &query.AnnotatedInput{
1662                                                         AccountID: "account1",
1663                                                 },
1664                                         },
1665                                 },
1666                         },
1667                 },
1668                 {
1669                         unconfirmedTxs: []*query.AnnotatedTx{
1670                                 &query.AnnotatedTx{
1671                                         ID:          bc.NewHash([32]byte{0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1672                                         Timestamp:   uint64(100),
1673                                         BlockID:     bc.NewHash([32]byte{0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1674                                         BlockHeight: uint64(100),
1675                                         Position:    uint32(101),
1676                                         Inputs: []*query.AnnotatedInput{
1677                                                 &query.AnnotatedInput{
1678                                                         AccountID: "account1",
1679                                                 },
1680                                         },
1681                                 },
1682                                 &query.AnnotatedTx{
1683                                         ID:          bc.NewHash([32]byte{0x02, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1684                                         Timestamp:   uint64(100),
1685                                         BlockID:     bc.NewHash([32]byte{0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1686                                         BlockHeight: uint64(100),
1687                                         Position:    uint32(120),
1688                                         Inputs: []*query.AnnotatedInput{
1689                                                 &query.AnnotatedInput{
1690                                                         AccountID: "account1",
1691                                                 },
1692                                         },
1693                                 },
1694                         },
1695                         confirmedTxs: []*query.AnnotatedTx{
1696                                 &query.AnnotatedTx{
1697                                         ID:          bc.NewHash([32]byte{0x03, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1698                                         Timestamp:   uint64(100),
1699                                         BlockID:     bc.NewHash([32]byte{0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1700                                         BlockHeight: uint64(100),
1701                                         Position:    uint32(130),
1702                                         Inputs: []*query.AnnotatedInput{
1703                                                 &query.AnnotatedInput{
1704                                                         AccountID: "account1",
1705                                                 },
1706                                         },
1707                                 },
1708                                 &query.AnnotatedTx{
1709                                         ID:          bc.NewHash([32]byte{0x04, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1710                                         Timestamp:   uint64(100),
1711                                         BlockID:     bc.NewHash([32]byte{0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1712                                         BlockHeight: uint64(100),
1713                                         Position:    uint32(140),
1714                                         Inputs: []*query.AnnotatedInput{
1715                                                 &query.AnnotatedInput{
1716                                                         AccountID: "account1",
1717                                                 },
1718                                         },
1719                                 },
1720                         },
1721                         height:      uint64(100),
1722                         accountID:   "",
1723                         startTxID:   "",
1724                         count:       uint(2),
1725                         unconfirmed: true,
1726                         want: []*query.AnnotatedTx{
1727                                 &query.AnnotatedTx{
1728                                         ID:          bc.NewHash([32]byte{0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1729                                         Timestamp:   uint64(100),
1730                                         BlockID:     bc.NewHash([32]byte{0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1731                                         BlockHeight: uint64(100),
1732                                         Position:    uint32(101),
1733                                         Inputs: []*query.AnnotatedInput{
1734                                                 &query.AnnotatedInput{
1735                                                         AccountID: "account1",
1736                                                 },
1737                                         },
1738                                 },
1739                                 &query.AnnotatedTx{
1740                                         ID:          bc.NewHash([32]byte{0x02, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1741                                         Timestamp:   uint64(100),
1742                                         BlockID:     bc.NewHash([32]byte{0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1743                                         BlockHeight: uint64(100),
1744                                         Position:    uint32(120),
1745                                         Inputs: []*query.AnnotatedInput{
1746                                                 &query.AnnotatedInput{
1747                                                         AccountID: "account1",
1748                                                 },
1749                                         },
1750                                 },
1751                         },
1752                 },
1753                 {
1754                         unconfirmedTxs: []*query.AnnotatedTx{
1755                                 &query.AnnotatedTx{
1756                                         ID:          bc.NewHash([32]byte{0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1757                                         Timestamp:   uint64(100),
1758                                         BlockID:     bc.NewHash([32]byte{0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1759                                         BlockHeight: uint64(100),
1760                                         Position:    uint32(101),
1761                                         Inputs: []*query.AnnotatedInput{
1762                                                 &query.AnnotatedInput{
1763                                                         AccountID: "account1",
1764                                                 },
1765                                         },
1766                                 },
1767                                 &query.AnnotatedTx{
1768                                         ID:          bc.NewHash([32]byte{0x02, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1769                                         Timestamp:   uint64(100),
1770                                         BlockID:     bc.NewHash([32]byte{0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1771                                         BlockHeight: uint64(100),
1772                                         Position:    uint32(120),
1773                                         Inputs: []*query.AnnotatedInput{
1774                                                 &query.AnnotatedInput{
1775                                                         AccountID: "account2",
1776                                                 },
1777                                         },
1778                                 },
1779                         },
1780                         confirmedTxs: []*query.AnnotatedTx{
1781                                 &query.AnnotatedTx{
1782                                         ID:          bc.NewHash([32]byte{0x03, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1783                                         Timestamp:   uint64(100),
1784                                         BlockID:     bc.NewHash([32]byte{0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1785                                         BlockHeight: uint64(100),
1786                                         Position:    uint32(130),
1787                                         Inputs: []*query.AnnotatedInput{
1788                                                 &query.AnnotatedInput{
1789                                                         AccountID: "account1",
1790                                                 },
1791                                         },
1792                                 },
1793                                 &query.AnnotatedTx{
1794                                         ID:          bc.NewHash([32]byte{0x04, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1795                                         Timestamp:   uint64(100),
1796                                         BlockID:     bc.NewHash([32]byte{0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1797                                         BlockHeight: uint64(100),
1798                                         Position:    uint32(140),
1799                                         Inputs: []*query.AnnotatedInput{
1800                                                 &query.AnnotatedInput{
1801                                                         AccountID: "account1",
1802                                                 },
1803                                         },
1804                                 },
1805                         },
1806                         height:      uint64(100),
1807                         accountID:   "account1",
1808                         startTxID:   "",
1809                         count:       uint(2),
1810                         unconfirmed: true,
1811                         want: []*query.AnnotatedTx{
1812                                 &query.AnnotatedTx{
1813                                         ID:          bc.NewHash([32]byte{0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1814                                         Timestamp:   uint64(100),
1815                                         BlockID:     bc.NewHash([32]byte{0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1816                                         BlockHeight: uint64(100),
1817                                         Position:    uint32(101),
1818                                         Inputs: []*query.AnnotatedInput{
1819                                                 &query.AnnotatedInput{
1820                                                         AccountID: "account1",
1821                                                 },
1822                                         },
1823                                 },
1824                         },
1825                 },
1826                 {
1827                         unconfirmedTxs: []*query.AnnotatedTx{
1828                                 &query.AnnotatedTx{
1829                                         ID:          bc.NewHash([32]byte{0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1830                                         Timestamp:   uint64(100),
1831                                         BlockID:     bc.NewHash([32]byte{0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1832                                         BlockHeight: uint64(100),
1833                                         Position:    uint32(101),
1834                                         Inputs: []*query.AnnotatedInput{
1835                                                 &query.AnnotatedInput{
1836                                                         AccountID: "account1",
1837                                                 },
1838                                         },
1839                                 },
1840                                 &query.AnnotatedTx{
1841                                         ID:          bc.NewHash([32]byte{0x02, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1842                                         Timestamp:   uint64(100),
1843                                         BlockID:     bc.NewHash([32]byte{0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1844                                         BlockHeight: uint64(100),
1845                                         Position:    uint32(120),
1846                                         Inputs: []*query.AnnotatedInput{
1847                                                 &query.AnnotatedInput{
1848                                                         AccountID: "account1",
1849                                                 },
1850                                         },
1851                                 },
1852                         },
1853                         confirmedTxs: []*query.AnnotatedTx{
1854                                 &query.AnnotatedTx{
1855                                         ID:          bc.NewHash([32]byte{0x03, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1856                                         Timestamp:   uint64(100),
1857                                         BlockID:     bc.NewHash([32]byte{0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1858                                         BlockHeight: uint64(100),
1859                                         Position:    uint32(130),
1860                                         Inputs: []*query.AnnotatedInput{
1861                                                 &query.AnnotatedInput{
1862                                                         AccountID: "account1",
1863                                                 },
1864                                         },
1865                                 },
1866                                 &query.AnnotatedTx{
1867                                         ID:          bc.NewHash([32]byte{0x04, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1868                                         Timestamp:   uint64(100),
1869                                         BlockID:     bc.NewHash([32]byte{0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1870                                         BlockHeight: uint64(100),
1871                                         Position:    uint32(140),
1872                                         Inputs: []*query.AnnotatedInput{
1873                                                 &query.AnnotatedInput{
1874                                                         AccountID: "account1",
1875                                                 },
1876                                         },
1877                                 },
1878                         },
1879                         height:      uint64(100),
1880                         accountID:   "",
1881                         startTxID:   hex.EncodeToString([]byte{0x02, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1882                         count:       uint(2),
1883                         unconfirmed: true,
1884                         want: []*query.AnnotatedTx{
1885                                 &query.AnnotatedTx{
1886                                         ID:          bc.NewHash([32]byte{0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1887                                         Timestamp:   uint64(100),
1888                                         BlockID:     bc.NewHash([32]byte{0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1889                                         BlockHeight: uint64(100),
1890                                         Position:    uint32(101),
1891                                         Inputs: []*query.AnnotatedInput{
1892                                                 &query.AnnotatedInput{
1893                                                         AccountID: "account1",
1894                                                 },
1895                                         },
1896                                 },
1897                         },
1898                 },
1899                 {
1900                         unconfirmedTxs: []*query.AnnotatedTx{
1901                                 &query.AnnotatedTx{
1902                                         ID:          bc.NewHash([32]byte{0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1903                                         Timestamp:   uint64(100),
1904                                         BlockID:     bc.NewHash([32]byte{0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1905                                         BlockHeight: uint64(100),
1906                                         Position:    uint32(101),
1907                                         Inputs: []*query.AnnotatedInput{
1908                                                 &query.AnnotatedInput{
1909                                                         AccountID: "account1",
1910                                                 },
1911                                         },
1912                                 },
1913                                 &query.AnnotatedTx{
1914                                         ID:          bc.NewHash([32]byte{0x02, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1915                                         Timestamp:   uint64(100),
1916                                         BlockID:     bc.NewHash([32]byte{0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1917                                         BlockHeight: uint64(100),
1918                                         Position:    uint32(120),
1919                                         Inputs: []*query.AnnotatedInput{
1920                                                 &query.AnnotatedInput{
1921                                                         AccountID: "account1",
1922                                                 },
1923                                         },
1924                                 },
1925                         },
1926                         confirmedTxs: []*query.AnnotatedTx{
1927                                 &query.AnnotatedTx{
1928                                         ID:          bc.NewHash([32]byte{0x03, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1929                                         Timestamp:   uint64(100),
1930                                         BlockID:     bc.NewHash([32]byte{0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1931                                         BlockHeight: uint64(100),
1932                                         Position:    uint32(130),
1933                                         Inputs: []*query.AnnotatedInput{
1934                                                 &query.AnnotatedInput{
1935                                                         AccountID: "account1",
1936                                                 },
1937                                         },
1938                                 },
1939                                 &query.AnnotatedTx{
1940                                         ID:          bc.NewHash([32]byte{0x04, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1941                                         Timestamp:   uint64(100),
1942                                         BlockID:     bc.NewHash([32]byte{0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1943                                         BlockHeight: uint64(100),
1944                                         Position:    uint32(140),
1945                                         Inputs: []*query.AnnotatedInput{
1946                                                 &query.AnnotatedInput{
1947                                                         AccountID: "account1",
1948                                                 },
1949                                         },
1950                                 },
1951                         },
1952                         height:      uint64(100),
1953                         accountID:   "",
1954                         startTxID:   hex.EncodeToString([]byte{0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
1955                         count:       uint(2),
1956                         unconfirmed: true,
1957                         want:        []*query.AnnotatedTx{},
1958                 },
1959         }
1960
1961         for i, c := range cases {
1962                 testDB := dbm.NewDB("testdb", "leveldb", "temp")
1963                 walletStore := NewWalletStore(testDB)
1964                 ws := walletStore.InitBatch()
1965                 // store unconfirmed txs
1966                 for _, tx := range c.unconfirmedTxs {
1967                         if err := ws.SetUnconfirmedTransaction(tx.ID.String(), tx); err != nil {
1968                                 t.Fatal(err)
1969                         }
1970                 }
1971
1972                 // store confirmed txs
1973                 for _, tx := range c.confirmedTxs {
1974                         if err := ws.SetTransaction(c.height, tx); err != nil {
1975                                 t.Fatal(err)
1976                         }
1977                 }
1978
1979                 if err := ws.CommitBatch(); err != nil {
1980                         t.Fatal(err)
1981                 }
1982
1983                 // get txs by given accountID, startID, count, unconfirmed
1984                 gotTxs, err := ws.ListTransactions(c.accountID, c.startTxID, c.count, c.unconfirmed)
1985                 if err != nil {
1986                         t.Fatal(err)
1987                 }
1988
1989                 sort.Sort(SortAnnotatedTxs(gotTxs))
1990                 sort.Sort(SortAnnotatedTxs(c.want))
1991
1992                 if !testutil.DeepEqual(gotTxs, c.want) {
1993                         t.Errorf("case %v: list transactions, got: %v, want: %v.", i, gotTxs, c.want)
1994                 }
1995
1996                 testDB.Close()
1997                 os.RemoveAll("temp")
1998         }
1999 }
2000
2001 type SortAnnotatedTxs []*query.AnnotatedTx
2002
2003 func (s SortAnnotatedTxs) Len() int { return len(s) }
2004 func (s SortAnnotatedTxs) Less(i, j int) bool {
2005         return bytes.Compare(s[i].ID.Bytes(), s[j].ID.Bytes()) < 0
2006 }
2007 func (s SortAnnotatedTxs) Swap(i, j int) { s[i], s[j] = s[j], s[i] }