OSDN Git Service

add TestListAccounts
[bytom/vapor.git] / database / account_store_test.go
1 package database
2
3 import (
4         "os"
5         "testing"
6
7         "github.com/vapor/common"
8         "github.com/vapor/testutil"
9
10         "github.com/vapor/blockchain/signers"
11         "github.com/vapor/crypto/ed25519/chainkd"
12
13         acc "github.com/vapor/account"
14         dbm "github.com/vapor/database/leveldb"
15         "github.com/vapor/protocol/bc"
16 )
17
18 func TestDeleteAccount(t *testing.T) {
19         cases := []struct {
20                 accounts      []*acc.Account
21                 deleteAccount *acc.Account
22                 want          []*acc.Account
23         }{
24                 {
25                         accounts:      []*acc.Account{},
26                         deleteAccount: &acc.Account{},
27                         want:          []*acc.Account{},
28                 },
29                 {
30                         accounts: []*acc.Account{},
31                         deleteAccount: &acc.Account{
32                                 ID:    "id-1",
33                                 Alias: "alias-1",
34                         },
35                         want: []*acc.Account{},
36                 },
37                 {
38                         accounts: []*acc.Account{
39                                 &acc.Account{
40                                         ID:    "id-1",
41                                         Alias: "alias-1",
42                                 },
43                                 &acc.Account{
44                                         ID:    "id-2",
45                                         Alias: "alias-2",
46                                 },
47                         },
48                         deleteAccount: &acc.Account{},
49                         want: []*acc.Account{
50                                 &acc.Account{
51                                         ID:    "id-1",
52                                         Alias: "alias-1",
53                                 },
54                                 &acc.Account{
55                                         ID:    "id-2",
56                                         Alias: "alias-2",
57                                 },
58                         },
59                 },
60                 {
61                         accounts: []*acc.Account{
62                                 &acc.Account{
63                                         ID:    "id-1",
64                                         Alias: "alias-1",
65                                 },
66                                 &acc.Account{
67                                         ID:    "id-2",
68                                         Alias: "alias-2",
69                                 },
70                         },
71                         deleteAccount: &acc.Account{
72                                 ID:    "id-3",
73                                 Alias: "alias-3",
74                         },
75                         want: []*acc.Account{
76                                 &acc.Account{
77                                         ID:    "id-1",
78                                         Alias: "alias-1",
79                                 },
80                                 &acc.Account{
81                                         ID:    "id-2",
82                                         Alias: "alias-2",
83                                 },
84                         },
85                 },
86                 {
87                         accounts: []*acc.Account{
88                                 &acc.Account{
89                                         ID:    "id-1",
90                                         Alias: "alias-1",
91                                 },
92                                 &acc.Account{
93                                         ID:    "id-2",
94                                         Alias: "alias-2",
95                                 },
96                         },
97                         deleteAccount: &acc.Account{
98                                 ID:    "id-1",
99                                 Alias: "alias-1",
100                         },
101                         want: []*acc.Account{
102                                 &acc.Account{
103                                         ID:    "id-2",
104                                         Alias: "alias-2",
105                                 },
106                         },
107                 },
108         }
109
110         for i, c := range cases {
111                 testDB := dbm.NewDB("testdb", "leveldb", "temp")
112                 accountStore := NewAccountStore(testDB)
113                 as := accountStore.InitBatch()
114                 // store mock accounts
115                 for _, a := range c.accounts {
116                         if err := as.SetAccount(a); err != nil {
117                                 t.Fatal(err)
118                         }
119                 }
120
121                 // delete account
122                 if err := as.DeleteAccount(c.deleteAccount); err != nil {
123                         t.Fatal(err)
124                 }
125
126                 if err := as.CommitBatch(); err != nil {
127                         t.Fatal(err)
128                 }
129
130                 // get account by deleteAccount.ID, it should print ErrFindAccount
131                 if _, err := as.GetAccountByID(c.deleteAccount.ID); err != acc.ErrFindAccount {
132                         t.Fatal(err)
133                 }
134
135                 for _, a := range c.want {
136                         if _, err := as.GetAccountByID(a.ID); err != nil {
137                                 t.Errorf("case %v: cann't find account, err: %v", i, err)
138                         }
139
140                         if _, err := as.GetAccountByAlias(a.Alias); err != nil {
141                                 t.Errorf("case %v: cann't find account, err: %v", i, err)
142                         }
143                 }
144
145                 testDB.Close()
146                 os.RemoveAll("temp")
147         }
148 }
149
150 func TestDeleteStandardUTXO(t *testing.T) {
151         cases := []struct {
152                 utxos      []*acc.UTXO
153                 deleteUTXO *acc.UTXO
154                 want       []*acc.UTXO
155         }{
156                 {
157                         utxos:      []*acc.UTXO{},
158                         deleteUTXO: &acc.UTXO{},
159                         want:       []*acc.UTXO{},
160                 },
161                 {
162                         utxos: []*acc.UTXO{
163                                 &acc.UTXO{
164                                         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}),
165                                 },
166                         },
167                         deleteUTXO: &acc.UTXO{
168                                 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}),
169                         },
170                         want: []*acc.UTXO{},
171                 },
172                 {
173                         utxos: []*acc.UTXO{
174                                 &acc.UTXO{
175                                         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}),
176                                 },
177                                 &acc.UTXO{
178                                         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}),
179                                 },
180                                 &acc.UTXO{
181                                         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}),
182                                 },
183                                 &acc.UTXO{
184                                         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}),
185                                 },
186                                 &acc.UTXO{
187                                         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}),
188                                 },
189                                 &acc.UTXO{
190                                         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}),
191                                 },
192                         },
193                         deleteUTXO: &acc.UTXO{},
194                         want: []*acc.UTXO{
195                                 &acc.UTXO{
196                                         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}),
197                                 },
198                                 &acc.UTXO{
199                                         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}),
200                                 },
201                                 &acc.UTXO{
202                                         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}),
203                                 },
204                                 &acc.UTXO{
205                                         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}),
206                                 },
207                                 &acc.UTXO{
208                                         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}),
209                                 },
210                                 &acc.UTXO{
211                                         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}),
212                                 },
213                         },
214                 },
215                 {
216                         utxos: []*acc.UTXO{},
217                         deleteUTXO: &acc.UTXO{
218                                 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}),
219                         },
220                         want: []*acc.UTXO{},
221                 },
222                 {
223                         utxos: []*acc.UTXO{
224                                 &acc.UTXO{
225                                         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}),
226                                 },
227                                 &acc.UTXO{
228                                         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}),
229                                 },
230                                 &acc.UTXO{
231                                         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}),
232                                 },
233                                 &acc.UTXO{
234                                         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}),
235                                 },
236                         },
237                         deleteUTXO: &acc.UTXO{
238                                 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}),
239                         },
240                         want: []*acc.UTXO{
241                                 &acc.UTXO{
242                                         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}),
243                                 },
244                                 &acc.UTXO{
245                                         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}),
246                                 },
247                                 &acc.UTXO{
248                                         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}),
249                                 },
250                         },
251                 },
252         }
253
254         for _, c := range cases {
255                 testDB := dbm.NewDB("testdb", "leveldb", "temp")
256                 accountStore := NewAccountStore(testDB)
257                 as := accountStore.InitBatch()
258                 // store mock utxos
259                 for _, utxo := range c.utxos {
260                         if err := as.SetStandardUTXO(utxo.OutputID, utxo); err != nil {
261                                 t.Fatal(err)
262                         }
263                 }
264
265                 // delete utxo
266                 as.DeleteStandardUTXO(c.deleteUTXO.OutputID)
267                 if err := as.CommitBatch(); err != nil {
268                         t.Fatal(err)
269                 }
270
271                 // get utxo by outputID
272                 for _, utxo := range c.want {
273                         if _, err := as.GetUTXO(utxo.OutputID); err != nil {
274                                 t.Fatal(err)
275                         }
276                 }
277
278                 testDB.Close()
279                 os.RemoveAll("temp")
280         }
281 }
282
283 func TestGetAccountIndex(t *testing.T) {
284         cases := []struct {
285                 account      *acc.Account
286                 currentIndex uint64
287                 want         uint64
288         }{
289                 {
290                         account: &acc.Account{
291                                 Signer: &signers.Signer{
292                                         XPubs: []chainkd.XPub{
293                                                 [64]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, 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},
294                                                 [64]byte{0x09, 0x09, 0x09, 0x01, 0x01, 0x00, 0x04, 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, 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},
295                                         },
296                                         KeyIndex: uint64(0),
297                                 },
298                         },
299                         currentIndex: uint64(0),
300                         want:         uint64(0),
301                 },
302                 {
303                         account: &acc.Account{
304                                 Signer: &signers.Signer{
305                                         XPubs: []chainkd.XPub{
306                                                 [64]byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 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, 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},
307                                                 [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},
308                                         },
309                                         KeyIndex: uint64(1),
310                                 },
311                         },
312                         currentIndex: uint64(1),
313                         want:         uint64(1),
314                 },
315                 {
316                         account: &acc.Account{
317                                 Signer: &signers.Signer{
318                                         XPubs: []chainkd.XPub{
319                                                 [64]byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 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, 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},
320                                                 [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},
321                                         },
322                                         KeyIndex: uint64(9),
323                                 },
324                         },
325                         currentIndex: uint64(1),
326                         want:         uint64(9),
327                 },
328                 {
329                         account: &acc.Account{
330                                 Signer: &signers.Signer{
331                                         XPubs: []chainkd.XPub{
332                                                 [64]byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 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, 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},
333                                                 [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},
334                                         },
335                                         KeyIndex: uint64(10),
336                                 },
337                         },
338                         currentIndex: uint64(88),
339                         want:         uint64(88),
340                 },
341                 {
342                         account: &acc.Account{
343                                 Signer: &signers.Signer{
344                                         XPubs:    []chainkd.XPub{},
345                                         KeyIndex: uint64(0),
346                                 },
347                         },
348                         currentIndex: uint64(0),
349                         want:         uint64(0),
350                 },
351                 {
352                         account: &acc.Account{
353                                 Signer: &signers.Signer{
354                                         XPubs: []chainkd.XPub{
355                                                 [64]byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 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, 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},
356                                         },
357                                         KeyIndex: uint64(1),
358                                 },
359                         },
360                         currentIndex: uint64(77),
361                         want:         uint64(77),
362                 },
363         }
364
365         for i, c := range cases {
366                 testDB := dbm.NewDB("testdb", "leveldb", "temp")
367                 accountStore := NewAccountStore(testDB)
368                 as := accountStore.InitBatch()
369                 v := as.(*AccountStore)
370                 v.db.Set(accountIndexKey(c.account.XPubs), common.Unit64ToBytes(c.currentIndex))
371                 as.SetAccountIndex(c.account)
372                 if err := as.CommitBatch(); err != nil {
373                         t.Fatal(err)
374                 }
375
376                 gotIndex := as.GetAccountIndex(c.account.XPubs)
377                 if !testutil.DeepEqual(gotIndex, c.want) {
378                         t.Errorf("case %v: got incorrect account index, got: %v, want: %v.", i, gotIndex, c.want)
379                 }
380
381                 testDB.Close()
382                 os.RemoveAll("temp")
383         }
384 }
385
386 func TestGetBip44ContractIndex(t *testing.T) {
387         cases := []struct {
388                 accountID string
389                 change    bool
390                 index     uint64
391         }{
392                 {
393                         accountID: "",
394                         change:    false,
395                         index:     uint64(0),
396                 },
397                 {
398                         accountID: "account1",
399                         change:    true,
400                         index:     uint64(0),
401                 },
402                 {
403                         accountID: "account1",
404                         change:    false,
405                         index:     uint64(0),
406                 },
407                 {
408                         accountID: "account1",
409                         change:    true,
410                         index:     uint64(100),
411                 },
412         }
413
414         for i, c := range cases {
415                 testDB := dbm.NewDB("testdb", "leveldb", "temp")
416                 accountStore := NewAccountStore(testDB)
417                 as := accountStore.InitBatch()
418                 as.SetBip44ContractIndex(c.accountID, c.change, c.index)
419                 if err := as.CommitBatch(); err != nil {
420                         t.Fatal(err)
421                 }
422
423                 gotIndex := as.GetBip44ContractIndex(c.accountID, c.change)
424                 if !testutil.DeepEqual(gotIndex, c.index) {
425                         t.Errorf("case %v: got incorrect bip44 contract index, got: %v, want: %v.", i, gotIndex, c.index)
426                 }
427
428                 testDB.Close()
429                 os.RemoveAll("temp")
430         }
431 }
432
433 func TestGetCoinbaseArbitrary(t *testing.T) {
434         cases := []struct {
435                 arbitrary []byte
436         }{
437                 {
438                         arbitrary: []byte{},
439                 },
440                 {
441                         arbitrary: []byte("test arbitrary"),
442                 },
443                 {
444                         arbitrary: []byte("test arbitrary test arbitrary test arbitrary test arbitrary test arbitrary"),
445                 },
446         }
447
448         for i, c := range cases {
449                 testDB := dbm.NewDB("testdb", "leveldb", "temp")
450                 accountStore := NewAccountStore(testDB)
451                 as := accountStore.InitBatch()
452                 as.SetCoinbaseArbitrary(c.arbitrary)
453                 if err := as.CommitBatch(); err != nil {
454                         t.Fatal(err)
455                 }
456
457                 gotArbitrary := as.GetCoinbaseArbitrary()
458                 if !testutil.DeepEqual(gotArbitrary, c.arbitrary) {
459                         t.Errorf("case %v: got incorrect arbitrary, got: %v, want: %v.", i, gotArbitrary, c.arbitrary)
460                 }
461
462                 testDB.Close()
463                 os.RemoveAll("temp")
464         }
465 }
466
467 func TestGetContractIndex(t *testing.T) {
468         cases := []struct {
469                 accountID string
470                 index     uint64
471         }{
472                 {
473                         accountID: "",
474                         index:     uint64(0),
475                 },
476                 {
477                         accountID: "account1",
478                         index:     uint64(0),
479                 },
480                 {
481                         accountID: "",
482                         index:     uint64(1000),
483                 },
484                 {
485                         accountID: "account1",
486                         index:     uint64(8888),
487                 },
488         }
489
490         for i, c := range cases {
491                 testDB := dbm.NewDB("testdb", "leveldb", "temp")
492                 accountStore := NewAccountStore(testDB)
493                 as := accountStore.InitBatch()
494                 as.SetContractIndex(c.accountID, c.index)
495                 if err := as.CommitBatch(); err != nil {
496                         t.Fatal(err)
497                 }
498
499                 gotIndex := as.GetContractIndex(c.accountID)
500                 if !testutil.DeepEqual(gotIndex, c.index) {
501                         t.Errorf("case %v: got contract index, got: %v, want: %v.", i, gotIndex, c.index)
502                 }
503
504                 testDB.Close()
505                 os.RemoveAll("temp")
506         }
507 }
508
509 func TestGetControlProgram(t *testing.T) {
510         cases := []struct {
511                 hash    bc.Hash
512                 program *acc.CtrlProgram
513         }{
514                 {
515                         hash:    bc.NewHash([32]byte{}),
516                         program: &acc.CtrlProgram{},
517                 },
518                 {
519                         hash:    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}),
520                         program: &acc.CtrlProgram{},
521                 },
522                 {
523                         hash: bc.NewHash([32]byte{}),
524                         program: &acc.CtrlProgram{
525                                 AccountID: "account1",
526                                 Address:   "address",
527                         },
528                 },
529                 {
530                         hash: bc.NewHash([32]byte{0xff, 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}),
531                         program: &acc.CtrlProgram{
532                                 AccountID: "account1",
533                                 Address:   "address",
534                         },
535                 },
536         }
537
538         for i, c := range cases {
539                 testDB := dbm.NewDB("testdb", "leveldb", "temp")
540                 accountStore := NewAccountStore(testDB)
541                 as := accountStore.InitBatch()
542                 as.SetControlProgram(c.hash, c.program)
543                 if err := as.CommitBatch(); err != nil {
544                         t.Fatal(err)
545                 }
546
547                 gotProgram, err := as.GetControlProgram(c.hash)
548                 if err != nil {
549                         t.Fatal(err)
550                 }
551
552                 if !testutil.DeepEqual(gotProgram, c.program) {
553                         t.Errorf("case %v: got control program, got: %v, want: %v.", i, gotProgram, c.program)
554                 }
555
556                 testDB.Close()
557                 os.RemoveAll("temp")
558         }
559 }
560
561 func TestGetMiningAddress(t *testing.T) {
562         cases := []struct {
563                 program *acc.CtrlProgram
564         }{
565                 {
566                         program: &acc.CtrlProgram{},
567                 },
568                 {
569                         program: &acc.CtrlProgram{
570                                 AccountID: "account1",
571                         },
572                 },
573         }
574
575         for i, c := range cases {
576                 testDB := dbm.NewDB("testdb", "leveldb", "temp")
577                 accountStore := NewAccountStore(testDB)
578                 as := accountStore.InitBatch()
579                 if err := as.SetMiningAddress(c.program); err != nil {
580                         t.Fatal(err)
581                 }
582
583                 if err := as.CommitBatch(); err != nil {
584                         t.Fatal(err)
585                 }
586
587                 gotProgram, err := as.GetMiningAddress()
588                 if err != nil {
589                         t.Fatal(err)
590                 }
591
592                 if !testutil.DeepEqual(gotProgram, c.program) {
593                         t.Errorf("case %v: got mining address got: %v, want: %v.", i, gotProgram, c.program)
594                 }
595
596                 testDB.Close()
597                 os.RemoveAll("temp")
598         }
599 }
600
601 func TestListAccounts(t *testing.T) {
602         cases := []struct {
603                 accounts []*acc.Account
604                 id       string
605                 want     []*acc.Account
606         }{
607                 {
608                         accounts: []*acc.Account{},
609                         id:       "",
610                         want:     []*acc.Account{},
611                 },
612                 {
613                         accounts: []*acc.Account{
614                                 &acc.Account{
615                                         ID: "account1",
616                                 },
617                         },
618                         id: "account",
619                         want: []*acc.Account{
620                                 &acc.Account{
621                                         ID: "account1",
622                                 },
623                         },
624                 },
625                 {
626                         accounts: []*acc.Account{
627                                 &acc.Account{
628                                         ID: "account2",
629                                 },
630                                 &acc.Account{
631                                         ID: "test1",
632                                 },
633                         },
634                         id: "account",
635                         want: []*acc.Account{
636                                 &acc.Account{
637                                         ID: "account2",
638                                 },
639                         },
640                 },
641                 {
642                         accounts: []*acc.Account{},
643                         id:       "account",
644                         want:     []*acc.Account{},
645                 },
646                 {
647                         accounts: []*acc.Account{
648                                 &acc.Account{
649                                         ID: "account1",
650                                 },
651                                 &acc.Account{
652                                         ID: "test1",
653                                 },
654                         },
655                         id: "",
656                         want: []*acc.Account{
657                                 &acc.Account{
658                                         ID: "account1",
659                                 },
660                                 &acc.Account{
661                                         ID: "test1",
662                                 },
663                         },
664                 },
665                 {
666                         accounts: []*acc.Account{
667                                 &acc.Account{
668                                         ID: "account1",
669                                 },
670                                 &acc.Account{
671                                         ID: "test1",
672                                 },
673                                 &acc.Account{
674                                         ID: "account11",
675                                 },
676                                 &acc.Account{
677                                         ID: "account2",
678                                 },
679                                 &acc.Account{
680                                         ID: "account112",
681                                 },
682                         },
683                         id: "account1",
684                         want: []*acc.Account{
685                                 &acc.Account{
686                                         ID: "account1",
687                                 },
688                                 &acc.Account{
689                                         ID: "account11",
690                                 },
691                                 &acc.Account{
692                                         ID: "account112",
693                                 },
694                         },
695                 },
696         }
697
698         for i, c := range cases {
699                 testDB := dbm.NewDB("testdb", "leveldb", "temp")
700                 accountStore := NewAccountStore(testDB)
701                 as := accountStore.InitBatch()
702                 for _, a := range c.accounts {
703                         if err := as.SetAccount(a); err != nil {
704                                 t.Fatal(err)
705                         }
706                 }
707
708                 if err := as.CommitBatch(); err != nil {
709                         t.Fatal(err)
710                 }
711
712                 gotAccounts, err := as.ListAccounts(c.id)
713                 if err != nil {
714                         t.Fatal(err)
715                 }
716
717                 if !testutil.DeepEqual(gotAccounts, c.want) {
718                         t.Errorf("case %v: list accounts, got: %v, want: %v.", i, gotAccounts, c.want)
719                 }
720
721                 testDB.Close()
722                 os.RemoveAll("temp")
723         }
724 }