OSDN Git Service

fix test
[bytom/vapor.git] / database / account_store.go
1 package database
2
3 import (
4         "strings"
5
6         "github.com/vapor/common"
7         "github.com/vapor/crypto/ed25519/chainkd"
8         dbm "github.com/vapor/database/leveldb"
9         "github.com/vapor/protocol/bc"
10 )
11
12 // AccountStorer interface contains account storage functions.
13 type AccountStorer interface {
14         InitBatch()
15         CommitBatch()
16         SetAccount(string, string, []byte)
17         SetAccountIndex([]chainkd.XPub, uint64)
18         GetAccountByAccountAlias(string) []byte
19         GetAccountByAccountID(string) []byte
20         GetAccountIndex([]chainkd.XPub) []byte
21         DeleteAccountByAccountAlias(string)
22         DeleteAccountByAccountID(string)
23         DeleteRawProgram(common.Hash)
24         DeleteBip44ContractIndex(string)
25         DeleteContractIndex(string)
26         GetContractIndex(string) []byte
27         GetAccountUTXOs(string) [][]byte
28         DeleteStandardUTXO(bc.Hash)
29         GetCoinbaseArbitrary() []byte
30         SetCoinbaseArbitrary([]byte)
31         GetMiningAddress() []byte
32         GetFirstAccount() ([]byte, error)
33         SetMiningAddress([]byte)
34         GetBip44ContractIndex(string, bool) []byte
35         GetRawProgram(common.Hash) []byte
36         GetAccounts(string) [][]byte
37         GetControlPrograms() ([][]byte, error)
38         SetRawProgram(common.Hash, []byte)
39         SetContractIndex(string, uint64)
40         SetBip44ContractIndex(string, bool, uint64)
41         GetUTXOs() [][]byte
42         GetStandardUTXO(bc.Hash) []byte
43         GetContractUTXO(bc.Hash) []byte
44         SetStandardUTXO(bc.Hash, []byte)
45 }
46
47 // AccountStore satisfies AccountStorer interface.
48 type AccountStore struct {
49         accountDB dbm.DB
50         batch     dbm.Batch
51 }
52
53 // NewAccountStore create new AccountStore.
54 func NewAccountStore(db dbm.DB) *AccountStore {
55         return &AccountStore{
56                 accountDB: db,
57                 batch:     nil,
58         }
59 }
60
61 // InitBatch initial batch
62 func (store *AccountStore) InitBatch() {
63         if store.batch == nil {
64                 store.batch = store.accountDB.NewBatch()
65         }
66 }
67
68 // CommitBatch commit batch
69 func (store *AccountStore) CommitBatch() {
70         if store.batch != nil {
71                 store.batch.Write()
72                 store.batch = nil
73         }
74 }
75
76 // SetAccount set account account ID, account alias and raw account.
77 func (store *AccountStore) SetAccount(accountID, accountAlias string, rawAccount []byte) {
78         batch := store.accountDB.NewBatch()
79         if store.batch != nil {
80                 batch = store.batch
81         }
82         batch.Set(AccountIDKey(accountID), rawAccount)
83         batch.Set(AccountAliasKey(accountAlias), []byte(accountID))
84         if store.batch == nil {
85                 batch.Write()
86         }
87 }
88
89 // DeleteAccount set account account ID, account alias and raw account.
90 func (store *AccountStore) DeleteAccount(accountID, accountAlias string) {
91         batch := store.accountDB.NewBatch()
92         if store.batch != nil {
93                 batch = store.batch
94         }
95         batch.Delete(AccountIDKey(accountID))
96         batch.Delete(AccountAliasKey(accountAlias))
97         if store.batch == nil {
98                 batch.Write()
99         }
100 }
101
102 // SetAccountIndex set account index
103 func (store *AccountStore) SetAccountIndex(xpubs []chainkd.XPub, keyIndex uint64) {
104         if store.batch == nil {
105                 store.accountDB.Set(AccountIndexKey(xpubs), common.Unit64ToBytes(keyIndex))
106         } else {
107                 store.batch.Set(AccountIndexKey(xpubs), common.Unit64ToBytes(keyIndex))
108         }
109 }
110
111 // GetAccountByAccountAlias get account by account alias
112 func (store *AccountStore) GetAccountByAccountAlias(accountAlias string) []byte {
113         return store.accountDB.Get(AccountAliasKey(accountAlias))
114 }
115
116 // GetAccountByAccountID get account by accountID
117 func (store *AccountStore) GetAccountByAccountID(accountID string) []byte {
118         return store.accountDB.Get(AccountIDKey(accountID))
119 }
120
121 // GetAccountIndex get account index by account xpubs
122 func (store *AccountStore) GetAccountIndex(xpubs []chainkd.XPub) []byte {
123         return store.accountDB.Get(AccountIndexKey(xpubs))
124 }
125
126 // DeleteAccountByAccountAlias delete account by account alias
127 func (store *AccountStore) DeleteAccountByAccountAlias(accountAlias string) {
128         if store.batch == nil {
129                 store.accountDB.Delete(AccountAliasKey(accountAlias))
130         } else {
131                 store.batch.Delete(AccountAliasKey(accountAlias))
132         }
133 }
134
135 // DeleteAccountByAccountID delete account by accountID
136 func (store *AccountStore) DeleteAccountByAccountID(accountID string) {
137         if store.batch == nil {
138                 store.accountDB.Delete(AccountIDKey(accountID))
139         } else {
140                 store.batch.Delete(AccountIDKey(accountID))
141         }
142 }
143
144 // DeleteRawProgram delete raw control program by hash
145 func (store *AccountStore) DeleteRawProgram(hash common.Hash) {
146         if store.batch == nil {
147                 store.accountDB.Delete(ContractKey(hash))
148         } else {
149                 store.batch.Delete(ContractKey(hash))
150         }
151 }
152
153 // DeleteBip44ContractIndex delete bip44 contract index by accountID
154 func (store *AccountStore) DeleteBip44ContractIndex(accountID string) {
155         batch := store.accountDB.NewBatch()
156         if store.batch != nil {
157                 batch = store.batch
158         }
159         batch.Delete(Bip44ContractIndexKey(accountID, false))
160         batch.Delete(Bip44ContractIndexKey(accountID, true))
161         if store.batch == nil {
162                 batch.Write()
163         }
164 }
165
166 // DeleteContractIndex delete contract index by accountID
167 func (store *AccountStore) DeleteContractIndex(accountID string) {
168         if store.batch == nil {
169                 store.accountDB.Delete(ContractIndexKey(accountID))
170         } else {
171                 store.batch.Delete(ContractIndexKey(accountID))
172         }
173 }
174
175 // GetContractIndex get contract index
176 func (store *AccountStore) GetContractIndex(accountID string) []byte {
177         return store.accountDB.Get(ContractIndexKey(accountID))
178 }
179
180 // GetAccountUTXOs get account utxos by account id
181 func (store *AccountStore) GetAccountUTXOs(accountID string) [][]byte {
182         accountUtxoIter := store.accountDB.IteratorPrefix([]byte(UTXOPrefix))
183         defer accountUtxoIter.Release()
184
185         utxos := make([][]byte, 0)
186         for accountUtxoIter.Next() {
187                 utxos = append(utxos, accountUtxoIter.Value())
188         }
189         return utxos
190 }
191
192 // DeleteStandardUTXO delete utxo by outpu id
193 func (store *AccountStore) DeleteStandardUTXO(outputID bc.Hash) {
194         if store.batch == nil {
195                 store.accountDB.Delete(StandardUTXOKey(outputID))
196         } else {
197                 store.batch.Delete(StandardUTXOKey(outputID))
198         }
199 }
200
201 // GetCoinbaseArbitrary get coinbase arbitrary
202 func (store *AccountStore) GetCoinbaseArbitrary() []byte {
203         return store.accountDB.Get([]byte(CoinbaseAbKey))
204 }
205
206 // SetCoinbaseArbitrary set coinbase arbitrary
207 func (store *AccountStore) SetCoinbaseArbitrary(arbitrary []byte) {
208         if store.batch == nil {
209                 store.accountDB.Set([]byte(CoinbaseAbKey), arbitrary)
210         } else {
211                 store.batch.Set([]byte(CoinbaseAbKey), arbitrary)
212         }
213 }
214
215 // GetMiningAddress get mining address
216 func (store *AccountStore) GetMiningAddress() []byte {
217         return store.accountDB.Get([]byte(MiningAddressKey))
218 }
219
220 // GetFirstAccount get first account
221 func (store *AccountStore) GetFirstAccount() ([]byte, error) {
222         accountIter := store.accountDB.IteratorPrefix([]byte(AccountPrefix))
223         defer accountIter.Release()
224
225         if !accountIter.Next() {
226                 return nil, ErrFindAccount
227         }
228         return accountIter.Value(), nil
229 }
230
231 // SetMiningAddress set mining address
232 func (store *AccountStore) SetMiningAddress(rawProgram []byte) {
233         if store.batch == nil {
234                 store.accountDB.Set([]byte(MiningAddressKey), rawProgram)
235         } else {
236                 store.batch.Set([]byte(MiningAddressKey), rawProgram)
237         }
238 }
239
240 // GetBip44ContractIndex get bip44 contract index
241 func (store *AccountStore) GetBip44ContractIndex(accountID string, change bool) []byte {
242         return store.accountDB.Get(Bip44ContractIndexKey(accountID, change))
243 }
244
245 // GetRawProgram get raw control program
246 func (store *AccountStore) GetRawProgram(hash common.Hash) []byte {
247         return store.accountDB.Get(ContractKey(hash))
248 }
249
250 // GetAccounts get all accounts which name prfix is id.
251 func (store *AccountStore) GetAccounts(id string) [][]byte {
252         accountIter := store.accountDB.IteratorPrefix(AccountIDKey(strings.TrimSpace(id)))
253         defer accountIter.Release()
254
255         accounts := make([][]byte, 0)
256         for accountIter.Next() {
257                 accounts = append(accounts, accountIter.Value())
258         }
259         return accounts
260 }
261
262 // GetControlPrograms get all local control programs
263 func (store *AccountStore) GetControlPrograms() ([][]byte, error) {
264         cpIter := store.accountDB.IteratorPrefix([]byte(ContractPrefix))
265         defer cpIter.Release()
266
267         cps := make([][]byte, 0)
268         for cpIter.Next() {
269                 cps = append(cps, cpIter.Value())
270         }
271         return cps, nil
272 }
273
274 // SetRawProgram set raw program
275 func (store *AccountStore) SetRawProgram(hash common.Hash, program []byte) {
276         if store.batch == nil {
277                 store.accountDB.Set(ContractKey(hash), program)
278         } else {
279                 store.batch.Set(ContractKey(hash), program)
280         }
281 }
282
283 // SetContractIndex set contract index
284 func (store *AccountStore) SetContractIndex(accountID string, index uint64) {
285         if store.batch == nil {
286                 store.accountDB.Set(ContractIndexKey(accountID), common.Unit64ToBytes(index))
287         } else {
288                 store.batch.Set(ContractIndexKey(accountID), common.Unit64ToBytes(index))
289         }
290 }
291
292 // SetBip44ContractIndex set contract index
293 func (store *AccountStore) SetBip44ContractIndex(accountID string, change bool, index uint64) {
294         if store.batch == nil {
295                 store.accountDB.Set(Bip44ContractIndexKey(accountID, change), common.Unit64ToBytes(index))
296         } else {
297                 store.batch.Set(Bip44ContractIndexKey(accountID, change), common.Unit64ToBytes(index))
298         }
299 }
300
301 // GetUTXOs get utxos by accountID
302 func (store *AccountStore) GetUTXOs() [][]byte {
303         utxoIter := store.accountDB.IteratorPrefix([]byte(UTXOPrefix))
304         defer utxoIter.Release()
305
306         utxos := make([][]byte, 0)
307         for utxoIter.Next() {
308                 utxos = append(utxos, utxoIter.Value())
309         }
310         return utxos
311 }
312
313 // GetStandardUTXO get standard utxo by id
314 func (store *AccountStore) GetStandardUTXO(outid bc.Hash) []byte {
315         return store.accountDB.Get(StandardUTXOKey(outid))
316 }
317
318 // GetContractUTXO get contract utxo
319 func (store *AccountStore) GetContractUTXO(outid bc.Hash) []byte {
320         return store.accountDB.Get(ContractUTXOKey(outid))
321 }
322
323 // SetStandardUTXO set standard utxo
324 func (store *AccountStore) SetStandardUTXO(outputID bc.Hash, data []byte) {
325         if store.batch == nil {
326                 store.accountDB.Set(StandardUTXOKey(outputID), data)
327         } else {
328                 store.batch.Set(StandardUTXOKey(outputID), data)
329         }
330 }