OSDN Git Service

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