OSDN Git Service

update dashboard. (#325)
[bytom/vapor.git] / database / wallet_store_test.go
1 package database
2
3 import (
4         "bytes"
5         "encoding/json"
6         "io/ioutil"
7         "os"
8         "reflect"
9         "sort"
10         "testing"
11
12         acc "github.com/vapor/account"
13         "github.com/vapor/asset"
14         "github.com/vapor/blockchain/pseudohsm"
15         "github.com/vapor/blockchain/query"
16         "github.com/vapor/crypto/ed25519/chainkd"
17         dbm "github.com/vapor/database/leveldb"
18         "github.com/vapor/protocol/bc"
19         "github.com/vapor/testutil"
20         "github.com/vapor/wallet"
21 )
22
23 func TestAccountIndexKey(t *testing.T) {
24         dirPath, err := ioutil.TempDir(".", "TestAccount")
25         if err != nil {
26                 t.Fatal(err)
27         }
28         defer os.RemoveAll(dirPath)
29
30         hsm, err := pseudohsm.New(dirPath)
31         if err != nil {
32                 t.Fatal(err)
33         }
34
35         xpub1, _, err := hsm.XCreate("TestAccountIndex1", "password", "en")
36         if err != nil {
37                 t.Fatal(err)
38         }
39
40         xpub2, _, err := hsm.XCreate("TestAccountIndex2", "password", "en")
41         if err != nil {
42                 t.Fatal(err)
43         }
44
45         xpubs1 := []chainkd.XPub{xpub1.XPub, xpub2.XPub}
46         xpubs2 := []chainkd.XPub{xpub2.XPub, xpub1.XPub}
47         if !reflect.DeepEqual(accountIndexKey(xpubs1), accountIndexKey(xpubs2)) {
48                 t.Fatal("accountIndexKey test err")
49         }
50
51         if reflect.DeepEqual(xpubs1, xpubs2) {
52                 t.Fatal("accountIndexKey test err")
53         }
54 }
55
56 func TestDeleteContractUTXO(t *testing.T) {
57         cases := []struct {
58                 utxos      []*acc.UTXO
59                 deleteUTXO *acc.UTXO
60                 want       []*acc.UTXO
61         }{
62                 {
63                         utxos:      []*acc.UTXO{},
64                         deleteUTXO: &acc.UTXO{},
65                         want:       []*acc.UTXO{},
66                 },
67                 {
68                         utxos: []*acc.UTXO{
69                                 &acc.UTXO{
70                                         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}),
71                                 },
72                         },
73                         deleteUTXO: &acc.UTXO{
74                                 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}),
75                         },
76                         want: []*acc.UTXO{},
77                 },
78                 {
79                         utxos: []*acc.UTXO{
80                                 &acc.UTXO{
81                                         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}),
82                                 },
83                                 &acc.UTXO{
84                                         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}),
85                                 },
86                                 &acc.UTXO{
87                                         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}),
88                                 },
89                                 &acc.UTXO{
90                                         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}),
91                                 },
92                                 &acc.UTXO{
93                                         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}),
94                                 },
95                                 &acc.UTXO{
96                                         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}),
97                                 },
98                         },
99                         deleteUTXO: &acc.UTXO{},
100                         want: []*acc.UTXO{
101                                 &acc.UTXO{
102                                         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}),
103                                 },
104                                 &acc.UTXO{
105                                         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}),
106                                 },
107                                 &acc.UTXO{
108                                         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}),
109                                 },
110                                 &acc.UTXO{
111                                         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}),
112                                 },
113                                 &acc.UTXO{
114                                         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}),
115                                 },
116                                 &acc.UTXO{
117                                         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}),
118                                 },
119                         },
120                 },
121                 {
122                         utxos: []*acc.UTXO{},
123                         deleteUTXO: &acc.UTXO{
124                                 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}),
125                         },
126                         want: []*acc.UTXO{},
127                 },
128                 {
129                         utxos: []*acc.UTXO{
130                                 &acc.UTXO{
131                                         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}),
132                                 },
133                                 &acc.UTXO{
134                                         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}),
135                                 },
136                                 &acc.UTXO{
137                                         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}),
138                                 },
139                                 &acc.UTXO{
140                                         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}),
141                                 },
142                         },
143                         deleteUTXO: &acc.UTXO{
144                                 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}),
145                         },
146                         want: []*acc.UTXO{
147                                 &acc.UTXO{
148                                         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}),
149                                 },
150                                 &acc.UTXO{
151                                         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}),
152                                 },
153                                 &acc.UTXO{
154                                         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}),
155                                 },
156                         },
157                 },
158         }
159
160         for _, c := range cases {
161                 testDB := dbm.NewDB("testdb", "leveldb", "temp")
162                 accountStore := NewAccountStore(testDB)
163                 walletStore := NewWalletStore(testDB)
164                 ws := walletStore.InitBatch()
165                 // store mock utxos
166                 for _, utxo := range c.utxos {
167                         if err := ws.SetContractUTXO(utxo.OutputID, utxo); err != nil {
168                                 t.Fatal(err)
169                         }
170                 }
171
172                 // delete utxo
173                 ws.DeleteContractUTXO(c.deleteUTXO.OutputID)
174                 if err := ws.CommitBatch(); err != nil {
175                         t.Fatal(err)
176                 }
177
178                 // get utxo by outputID
179                 for _, utxo := range c.want {
180                         if _, err := accountStore.GetUTXO(utxo.OutputID); err != nil {
181                                 t.Fatal(err)
182                         }
183                 }
184
185                 testDB.Close()
186                 os.RemoveAll("temp")
187         }
188 }
189
190 func TestDeleteRecoveryStatus(t *testing.T) {
191         cases := []struct {
192                 state *wallet.RecoveryState
193         }{
194                 {
195                         state: &wallet.RecoveryState{},
196                 },
197                 {
198                         state: &wallet.RecoveryState{
199                                 XPubs: []chainkd.XPub{
200                                         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}),
201                                 },
202                         },
203                 },
204                 {
205                         state: &wallet.RecoveryState{
206                                 XPubs: []chainkd.XPub{
207                                         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}),
208                                         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}),
209                                         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}),
210                                         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}),
211                                         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}),
212                                         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}),
213                                         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}),
214                                         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}),
215                                         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}),
216                                         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}),
217                                         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}),
218                                         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}),
219                                 },
220                         },
221                 },
222         }
223
224         for i, c := range cases {
225                 testDB := dbm.NewDB("testdb", "leveldb", "temp")
226                 walletStore := NewWalletStore(testDB)
227                 ws := walletStore.InitBatch()
228                 if err := ws.SetRecoveryStatus(c.state); err != nil {
229                         t.Fatal(err)
230                 }
231
232                 if err := ws.CommitBatch(); err != nil {
233                         t.Fatal(err)
234                 }
235
236                 gotState, err := ws.GetRecoveryStatus()
237                 if err != nil {
238                         t.Fatal(err)
239                 }
240
241                 if !testutil.DeepEqual(gotState, c.state) {
242                         t.Errorf("case %v: got recovery status, got: %v, want: %v.", i, gotState, c.state)
243                 }
244
245                 ws = walletStore.InitBatch()
246                 ws.DeleteRecoveryStatus()
247                 if err := ws.CommitBatch(); err != nil {
248                         t.Fatal(err)
249                 }
250
251                 gotState, err = ws.GetRecoveryStatus()
252                 if err == nil {
253                         t.Errorf("case %v: got state should fail.", i)
254                 }
255
256                 testDB.Close()
257                 os.RemoveAll("temp")
258         }
259 }
260
261 func TestGetWalletInfo(t *testing.T) {
262         cases := []struct {
263                 state *wallet.StatusInfo
264         }{
265                 {
266                         state: &wallet.StatusInfo{},
267                 },
268                 {
269                         state: &wallet.StatusInfo{
270                                 Version:    uint(0),
271                                 WorkHeight: uint64(9),
272                                 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}),
273                                 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}),
274                                 BestHeight: uint64(0),
275                         },
276                 },
277                 {
278                         state: &wallet.StatusInfo{
279                                 Version:    uint(9),
280                                 WorkHeight: uint64(9999999),
281                                 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}),
282                                 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}),
283                                 BestHeight: uint64(100000),
284                         },
285                 },
286         }
287
288         for i, c := range cases {
289                 testDB := dbm.NewDB("testdb", "leveldb", "temp")
290                 walletStore := NewWalletStore(testDB)
291                 ws := walletStore.InitBatch()
292                 if err := ws.SetWalletInfo(c.state); err != nil {
293                         t.Fatal(err)
294                 }
295
296                 if err := ws.CommitBatch(); err != nil {
297                         t.Fatal(err)
298                 }
299
300                 gotState, err := ws.GetWalletInfo()
301                 if err != nil {
302                         t.Fatal(err)
303                 }
304
305                 if !testutil.DeepEqual(gotState, c.state) {
306                         t.Errorf("case %v: got wallet info, got: %v, want: %v.", i, gotState, c.state)
307                 }
308
309                 testDB.Close()
310                 os.RemoveAll("temp")
311         }
312 }
313
314 func TestDeleteUnconfirmedTransaction(t *testing.T) {
315         cases := []struct {
316                 tx *query.AnnotatedTx
317         }{
318                 {
319                         tx: &query.AnnotatedTx{},
320                 },
321                 {
322                         tx: &query.AnnotatedTx{
323                                 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}),
324                                 Timestamp:   uint64(100),
325                                 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}),
326                                 BlockHeight: uint64(100),
327                                 Position:    uint32(100),
328                         },
329                 },
330         }
331
332         for i, c := range cases {
333                 testDB := dbm.NewDB("testdb", "leveldb", "temp")
334                 walletStore := NewWalletStore(testDB)
335                 ws := walletStore.InitBatch()
336                 if err := ws.SetUnconfirmedTransaction(c.tx.ID.String(), c.tx); err != nil {
337                         t.Fatal(err)
338                 }
339
340                 if err := ws.CommitBatch(); err != nil {
341                         t.Fatal(err)
342                 }
343
344                 gotTx, err := ws.GetUnconfirmedTransaction(c.tx.ID.String())
345                 if err != nil {
346                         t.Fatal(err)
347                 }
348
349                 if !testutil.DeepEqual(gotTx, c.tx) {
350                         t.Errorf("case %v: got unconfirmed transaction, got: %v, want: %v.", i, gotTx, c.tx)
351                 }
352
353                 ws = walletStore.InitBatch()
354                 ws.DeleteUnconfirmedTransaction(c.tx.ID.String())
355                 if err := ws.CommitBatch(); err != nil {
356                         t.Fatal(err)
357                 }
358
359                 gotTx, err = ws.GetUnconfirmedTransaction(c.tx.ID.String())
360                 if err == nil {
361                         t.Errorf("case %v: got unconfirmed transaction should fail.", i)
362                 }
363
364                 testDB.Close()
365                 os.RemoveAll("temp")
366         }
367 }
368
369 func TestListUnconfirmedTransactions(t *testing.T) {
370         cases := []struct {
371                 txs []*query.AnnotatedTx
372         }{
373                 {
374                         txs: []*query.AnnotatedTx{},
375                 },
376                 {
377                         txs: []*query.AnnotatedTx{
378                                 &query.AnnotatedTx{
379                                         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}),
380                                         Timestamp:   uint64(100),
381                                         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}),
382                                         BlockHeight: uint64(100),
383                                         Position:    uint32(100),
384                                 },
385                         },
386                 },
387                 {
388                         txs: []*query.AnnotatedTx{
389                                 &query.AnnotatedTx{
390                                         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}),
391                                         Timestamp:   uint64(100),
392                                         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}),
393                                         BlockHeight: uint64(100),
394                                         Position:    uint32(100),
395                                 },
396                                 &query.AnnotatedTx{
397                                         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}),
398                                         Timestamp:   uint64(100),
399                                         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}),
400                                         BlockHeight: uint64(100),
401                                         Position:    uint32(100),
402                                 },
403                                 &query.AnnotatedTx{
404                                         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}),
405                                         Timestamp:   uint64(100),
406                                         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}),
407                                         BlockHeight: uint64(100),
408                                         Position:    uint32(100),
409                                 },
410                                 &query.AnnotatedTx{
411                                         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}),
412                                         Timestamp:   uint64(100),
413                                         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}),
414                                         BlockHeight: uint64(100),
415                                         Position:    uint32(100),
416                                 },
417                                 &query.AnnotatedTx{
418                                         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}),
419                                         Timestamp:   uint64(100),
420                                         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}),
421                                         BlockHeight: uint64(100),
422                                         Position:    uint32(100),
423                                 },
424                                 &query.AnnotatedTx{
425                                         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}),
426                                         Timestamp:   uint64(100),
427                                         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}),
428                                         BlockHeight: uint64(100),
429                                         Position:    uint32(100),
430                                 },
431                                 &query.AnnotatedTx{
432                                         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}),
433                                         Timestamp:   uint64(100),
434                                         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}),
435                                         BlockHeight: uint64(100),
436                                         Position:    uint32(100),
437                                 },
438                         },
439                 },
440         }
441
442         for i, c := range cases {
443                 testDB := dbm.NewDB("testdb", "leveldb", "temp")
444                 walletStore := NewWalletStore(testDB)
445                 ws := walletStore.InitBatch()
446                 for _, tx := range c.txs {
447                         if err := ws.SetUnconfirmedTransaction(tx.ID.String(), tx); err != nil {
448                                 t.Fatal(err)
449                         }
450                 }
451
452                 if err := ws.CommitBatch(); err != nil {
453                         t.Fatal(err)
454                 }
455
456                 gotTxs, err := ws.ListUnconfirmedTransactions()
457                 if err != nil {
458                         t.Fatal(err)
459                 }
460
461                 sort.Sort(SortUnconfirmedTxs(gotTxs))
462                 sort.Sort(SortUnconfirmedTxs(c.txs))
463
464                 if !testutil.DeepEqual(gotTxs, c.txs) {
465                         t.Errorf("case %v: list unconfirmed transactions, got: %v, want: %v.", i, gotTxs, c.txs)
466                 }
467
468                 testDB.Close()
469                 os.RemoveAll("temp")
470         }
471 }
472
473 type SortUnconfirmedTxs []*query.AnnotatedTx
474
475 func (s SortUnconfirmedTxs) Len() int { return len(s) }
476 func (s SortUnconfirmedTxs) Less(i, j int) bool {
477         return bytes.Compare(s[i].ID.Bytes(), s[j].ID.Bytes()) < 0
478 }
479 func (s SortUnconfirmedTxs) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
480
481 func TestGetGlobalTransactionIndex(t *testing.T) {
482         cases := []struct {
483                 globalTxID string
484                 blockHash  bc.Hash
485                 position   uint64
486         }{
487                 {
488                         globalTxID: "",
489                         blockHash:  bc.NewHash([32]byte{}),
490                         position:   uint64(0),
491                 },
492                 {
493                         globalTxID: "8838474e18e945e2f648745a362ac6988bad172b0eef5c593038a2fc8b46261e",
494                         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}),
495                         position:   uint64(0),
496                 },
497                 {
498                         globalTxID: "d8de517917a591daa447d6be28ffb2fac866703e4feb65e86221be9a22d3033a",
499                         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}),
500                         position:   uint64(99),
501                 },
502                 {
503                         globalTxID: "f4c64e9f72623c26b06e17f909aec7c03c927fcf681781489257097e537b8d5a",
504                         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}),
505                         position:   uint64(99),
506                 },
507         }
508
509         for i, c := range cases {
510                 testDB := dbm.NewDB("testdb", "leveldb", "temp")
511                 walletStore := NewWalletStore(testDB)
512                 ws := walletStore.InitBatch()
513                 ws.SetGlobalTransactionIndex(c.globalTxID, &c.blockHash, c.position)
514
515                 if err := ws.CommitBatch(); err != nil {
516                         t.Fatal(err)
517                 }
518
519                 gotIndex := ws.GetGlobalTransactionIndex(c.globalTxID)
520                 wantIndex := CalcGlobalTxIndex(&c.blockHash, c.position)
521
522                 if !testutil.DeepEqual(gotIndex, wantIndex) {
523                         t.Errorf("case %v: got global transaction index, got: %v, want: %v.", i, gotIndex, wantIndex)
524                 }
525
526                 testDB.Close()
527                 os.RemoveAll("temp")
528         }
529 }
530
531 func TestGetAsset(t *testing.T) {
532         cases := []struct {
533                 asset *asset.Asset
534         }{
535                 {
536                         asset: &asset.Asset{
537                                 AssetID:       bc.NewAssetID([32]byte{}),
538                                 DefinitionMap: map[string]interface{}{},
539                         },
540                 },
541                 {
542                         asset: &asset.Asset{
543                                 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}),
544                                 DefinitionMap: map[string]interface{}{},
545                         },
546                 },
547                 {
548                         asset: &asset.Asset{
549                                 AssetID: bc.NewAssetID([32]byte{}),
550                                 DefinitionMap: map[string]interface{}{
551                                         "Name": "assetname",
552                                 },
553                         },
554                 },
555                 {
556                         asset: &asset.Asset{
557                                 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}),
558                                 DefinitionMap: map[string]interface{}{
559                                         "Name": "assetname",
560                                 },
561                         },
562                 },
563                 {
564                         asset: &asset.Asset{
565                                 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}),
566                                 DefinitionMap: map[string]interface{}{
567                                         "Name":   "assetname",
568                                         "Amount": "1000000",
569                                 },
570                         },
571                 },
572         }
573
574         for i, c := range cases {
575                 testDB := dbm.NewDB("testdb", "leveldb", "temp")
576                 walletStore := NewWalletStore(testDB)
577                 ws := walletStore.InitBatch()
578                 definitionByte, err := json.Marshal(c.asset.DefinitionMap)
579                 if err != nil {
580                         t.Fatal(err)
581                 }
582
583                 ws.SetAssetDefinition(&c.asset.AssetID, definitionByte)
584                 if err := ws.CommitBatch(); err != nil {
585                         t.Fatal(err)
586                 }
587
588                 gotAsset, err := ws.GetAsset(&c.asset.AssetID)
589                 if err != nil {
590                         t.Fatal(err)
591                 }
592
593                 if !testutil.DeepEqual(gotAsset.DefinitionMap, c.asset.DefinitionMap) {
594                         t.Errorf("case %v: got asset, got: %v, want: %v.", i, gotAsset.DefinitionMap, c.asset.DefinitionMap)
595                 }
596
597                 testDB.Close()
598                 os.RemoveAll("temp")
599         }
600 }
601
602 func TestDeleteTransactions(t *testing.T) {
603         cases := []struct {
604                 height uint64
605                 txs    []*query.AnnotatedTx
606         }{
607                 {
608                         height: uint64(0),
609                         txs:    []*query.AnnotatedTx{},
610                 },
611                 {
612                         height: uint64(0),
613                         txs: []*query.AnnotatedTx{
614                                 &query.AnnotatedTx{
615                                         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}),
616                                         Timestamp:   uint64(9988000),
617                                         BlockHeight: uint64(0),
618                                         Position:    uint32(2333),
619                                 },
620                         },
621                 },
622                 {
623                         height: uint64(1000000),
624                         txs: []*query.AnnotatedTx{
625                                 &query.AnnotatedTx{
626                                         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}),
627                                         Timestamp:   uint64(9988000),
628                                         BlockHeight: uint64(1000000),
629                                         Position:    uint32(0),
630                                 },
631                                 &query.AnnotatedTx{
632                                         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}),
633                                         Timestamp:   uint64(9988000),
634                                         BlockHeight: uint64(1000000),
635                                         Position:    uint32(1),
636                                 },
637                                 &query.AnnotatedTx{
638                                         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}),
639                                         Timestamp:   uint64(9988000),
640                                         BlockHeight: uint64(1000000),
641                                         Position:    uint32(2),
642                                 },
643                                 &query.AnnotatedTx{
644                                         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}),
645                                         Timestamp:   uint64(9988000),
646                                         BlockHeight: uint64(1000000),
647                                         Position:    uint32(3),
648                                 },
649                                 &query.AnnotatedTx{
650                                         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}),
651                                         Timestamp:   uint64(9988000),
652                                         BlockHeight: uint64(1000000),
653                                         Position:    uint32(4),
654                                 },
655                                 &query.AnnotatedTx{
656                                         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}),
657                                         Timestamp:   uint64(9988000),
658                                         BlockHeight: uint64(1000000),
659                                         Position:    uint32(5),
660                                 },
661                                 &query.AnnotatedTx{
662                                         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}),
663                                         Timestamp:   uint64(9988000),
664                                         BlockHeight: uint64(1000000),
665                                         Position:    uint32(6),
666                                 },
667                                 &query.AnnotatedTx{
668                                         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}),
669                                         Timestamp:   uint64(9988000),
670                                         BlockHeight: uint64(1000000),
671                                         Position:    uint32(7),
672                                 },
673                                 &query.AnnotatedTx{
674                                         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}),
675                                         Timestamp:   uint64(9988000),
676                                         BlockHeight: uint64(1000000),
677                                         Position:    uint32(8),
678                                 },
679                                 &query.AnnotatedTx{
680                                         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}),
681                                         Timestamp:   uint64(9988000),
682                                         BlockHeight: uint64(1000000),
683                                         Position:    uint32(9),
684                                 },
685                         },
686                 },
687         }
688
689         for i, c := range cases {
690                 testDB := dbm.NewDB("testdb", "leveldb", "temp")
691                 walletStore := NewWalletStore(testDB)
692                 ws := walletStore.InitBatch()
693                 // store txs by given height
694                 for _, tx := range c.txs {
695                         if err := ws.SetTransaction(c.height, tx); err != nil {
696                                 t.Fatal(err)
697                         }
698                 }
699
700                 if err := ws.CommitBatch(); err != nil {
701                         t.Fatal(err)
702                 }
703
704                 // get tx by txID
705                 for j := 0; j < len(c.txs); j++ {
706                         gotTx, err := ws.GetTransaction(c.txs[j].ID.String())
707                         if err != nil {
708                                 t.Fatal(err)
709                         }
710
711                         if !testutil.DeepEqual(gotTx, c.txs[j]) {
712                                 t.Errorf("case %v: got transaction, got: %v, want: %v.", i, gotTx, c.txs[j])
713                         }
714                 }
715
716                 // delete all txs by given height
717                 ws = walletStore.InitBatch()
718                 ws.DeleteTransactions(c.height)
719                 if err := ws.CommitBatch(); err != nil {
720                         t.Fatal(err)
721                 }
722
723                 // get tx by txID, it should return err
724                 for _, tx := range c.txs {
725                         _, err := ws.GetTransaction(tx.ID.String())
726                         if err == nil {
727                                 t.Errorf("case: %v: it should return some err.", i)
728                         }
729                 }
730
731                 testDB.Close()
732                 os.RemoveAll("temp")
733         }
734 }
735
736 func TestDeleteWalletTransactions(t *testing.T) {
737         cases := []struct {
738                 height uint64
739                 txs    []*query.AnnotatedTx
740         }{
741                 {
742                         height: uint64(0),
743                         txs:    []*query.AnnotatedTx{},
744                 },
745                 {
746                         height: uint64(0),
747                         txs: []*query.AnnotatedTx{
748                                 &query.AnnotatedTx{
749                                         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}),
750                                         Timestamp:   uint64(9988000),
751                                         BlockHeight: uint64(0),
752                                         Position:    uint32(2333),
753                                 },
754                         },
755                 },
756                 {
757                         height: uint64(1000000),
758                         txs: []*query.AnnotatedTx{
759                                 &query.AnnotatedTx{
760                                         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}),
761                                         Timestamp:   uint64(9988000),
762                                         BlockHeight: uint64(1000000),
763                                         Position:    uint32(0),
764                                 },
765                                 &query.AnnotatedTx{
766                                         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}),
767                                         Timestamp:   uint64(9988000),
768                                         BlockHeight: uint64(1000000),
769                                         Position:    uint32(1),
770                                 },
771                                 &query.AnnotatedTx{
772                                         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}),
773                                         Timestamp:   uint64(9988000),
774                                         BlockHeight: uint64(1000000),
775                                         Position:    uint32(2),
776                                 },
777                                 &query.AnnotatedTx{
778                                         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}),
779                                         Timestamp:   uint64(9988000),
780                                         BlockHeight: uint64(1000000),
781                                         Position:    uint32(3),
782                                 },
783                                 &query.AnnotatedTx{
784                                         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}),
785                                         Timestamp:   uint64(9988000),
786                                         BlockHeight: uint64(1000000),
787                                         Position:    uint32(4),
788                                 },
789                                 &query.AnnotatedTx{
790                                         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}),
791                                         Timestamp:   uint64(9988000),
792                                         BlockHeight: uint64(1000000),
793                                         Position:    uint32(5),
794                                 },
795                                 &query.AnnotatedTx{
796                                         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}),
797                                         Timestamp:   uint64(9988000),
798                                         BlockHeight: uint64(1000000),
799                                         Position:    uint32(6),
800                                 },
801                                 &query.AnnotatedTx{
802                                         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}),
803                                         Timestamp:   uint64(9988000),
804                                         BlockHeight: uint64(1000000),
805                                         Position:    uint32(7),
806                                 },
807                                 &query.AnnotatedTx{
808                                         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}),
809                                         Timestamp:   uint64(9988000),
810                                         BlockHeight: uint64(1000000),
811                                         Position:    uint32(8),
812                                 },
813                                 &query.AnnotatedTx{
814                                         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}),
815                                         Timestamp:   uint64(9988000),
816                                         BlockHeight: uint64(1000000),
817                                         Position:    uint32(9),
818                                 },
819                         },
820                 },
821         }
822
823         for i, c := range cases {
824                 testDB := dbm.NewDB("testdb", "leveldb", "temp")
825                 walletStore := NewWalletStore(testDB)
826                 ws := walletStore.InitBatch()
827                 // store txs by given height
828                 for _, tx := range c.txs {
829                         if err := ws.SetTransaction(c.height, tx); err != nil {
830                                 t.Fatal(err)
831                         }
832                 }
833
834                 if err := ws.CommitBatch(); err != nil {
835                         t.Fatal(err)
836                 }
837
838                 // delete all txs
839                 ws = walletStore.InitBatch()
840                 ws.DeleteWalletTransactions()
841                 if err := ws.CommitBatch(); err != nil {
842                         t.Fatal(err)
843                 }
844
845                 // get tx by txID, it should return err
846                 for _, tx := range c.txs {
847                         _, err := ws.GetTransaction(tx.ID.String())
848                         if err == nil {
849                                 t.Errorf("case: %v: it should return some err.", i)
850                         }
851                 }
852
853                 testDB.Close()
854                 os.RemoveAll("temp")
855         }
856 }