OSDN Git Service

5f71fd984f67698a617c36b1032a8393b1e46700
[bytom/vapor.git] / wallet / wallet_store.go
1 package wallet
2
3 import (
4         "encoding/json"
5
6         "github.com/vapor/account"
7         "github.com/vapor/asset"
8         "github.com/vapor/blockchain/query"
9         "github.com/vapor/common"
10         dbm "github.com/vapor/database/leveldb"
11         "github.com/vapor/protocol/bc"
12 )
13
14 const (
15         UTXOPrefix     = "ACU:" //UTXOPrefix is StandardUTXOKey prefix
16         SUTXOPrefix    = "SCU:" //SUTXOPrefix is ContractUTXOKey prefix
17         contractPrefix = "Contract:"
18         accountPrefix  = "Account:"
19 )
20
21 // WalletStorer interface contains wallet storage functions.
22 type WalletStorer interface {
23         GetAssetDefinition(*bc.AssetID) []byte
24         SetAssetDefinition(*bc.AssetID, []byte)
25         GetRawProgram(common.Hash) []byte
26         GetAccountByAccountID(string) []byte
27         DeleteTransaction(uint64)
28         SetTransaction(uint64, uint32, string, []byte)
29         DeleteUnconfirmedTransaction(string)
30         SetGlobalTransactionIndex(string, *bc.Hash, uint64)
31         GetStandardUTXO(bc.Hash) []byte
32         GetTransaction(string) ([]byte, error)
33         GetGlobalTransaction(string) []byte
34         GetTransactions() ([]*query.AnnotatedTx, error)
35         GetUnconfirmedTransactions() ([]*query.AnnotatedTx, error)
36         GetUnconfirmedTransaction(string) []byte
37         SetUnconfirmedTransaction(string, []byte)
38         DeleteStardardUTXO(bc.Hash)
39         DeleteContractUTXO(bc.Hash)
40         SetStandardUTXO(bc.Hash, []byte)
41         SetContractUTXO(bc.Hash, []byte)
42         GetWalletInfo() []byte
43         SetWalletInfo([]byte)
44         DeleteWalletTransactions()
45         DeleteWalletUTXOs()
46         GetAccountUTXOs(key string) [][]byte
47         SetRecoveryStatus([]byte, []byte)
48         DeleteRecoveryStatus([]byte)
49         GetRecoveryStatus([]byte) []byte
50 }
51
52 // WalletStore store wallet using leveldb
53 type WalletStore struct {
54         DB dbm.DB
55 }
56
57 // NewWalletStore create new WalletStore struct
58 func NewWalletStore(db dbm.DB) *WalletStore {
59         return &WalletStore{
60                 DB: db,
61         }
62 }
63
64 // ContractKey account control promgram store prefix
65 func ContractKey(hash common.Hash) []byte {
66         return append([]byte(contractPrefix), hash[:]...)
67 }
68
69 // Key account store prefix
70 func Key(name string) []byte {
71         return append([]byte(accountPrefix), []byte(name)...)
72 }
73
74 // StandardUTXOKey makes an account unspent outputs key to store
75 func StandardUTXOKey(id bc.Hash) []byte {
76         name := id.String()
77         return []byte(UTXOPrefix + name)
78 }
79
80 // ContractUTXOKey makes a smart contract unspent outputs key to store
81 func ContractUTXOKey(id bc.Hash) []byte {
82         name := id.String()
83         return []byte(SUTXOPrefix + name)
84 }
85
86 // GetAssetDefinition get asset definition by assetiD
87 func (store *WalletStore) GetAssetDefinition(assetID *bc.AssetID) []byte {
88         return store.DB.Get(asset.ExtAssetKey(assetID))
89 }
90
91 // SetAssetDefinition set assetID and definition
92 func (store *WalletStore) SetAssetDefinition(assetID *bc.AssetID, definition []byte) {
93         store.DB.Set(asset.ExtAssetKey(assetID), definition)
94 }
95
96 // GetRawProgram get raw program by hash
97 func (store *WalletStore) GetRawProgram(hash common.Hash) []byte {
98         return store.DB.Get(ContractKey(hash))
99 }
100
101 // GetAccount get account value by account ID
102 func (store *WalletStore) GetAccountByAccountID(accountID string) []byte {
103         return store.DB.Get(Key(accountID))
104 }
105
106 // DeleteTransaction delete transactions when orphan block rollback
107 func (store *WalletStore) DeleteTransaction(height uint64) {
108         tmpTx := query.AnnotatedTx{}
109         batch := store.DB.NewBatch()
110         txIter := store.DB.IteratorPrefix(calcDeleteKey(height))
111         defer txIter.Release()
112
113         for txIter.Next() {
114                 if err := json.Unmarshal(txIter.Value(), &tmpTx); err == nil {
115                         batch.Delete(calcTxIndexKey(tmpTx.ID.String()))
116                 }
117                 batch.Delete(txIter.Key())
118         }
119         batch.Write()
120 }
121
122 // SetTransaction set raw transaction by block height and tx position
123 func (store *WalletStore) SetTransaction(height uint64, position uint32, txID string, rawTx []byte) {
124         batch := store.DB.NewBatch()
125         batch.Set(calcAnnotatedKey(formatKey(height, position)), rawTx)
126         batch.Set(calcTxIndexKey(txID), []byte(formatKey(height, position)))
127         batch.Write()
128 }
129
130 // DeleteUnconfirmedTransaction delete unconfirmed tx by txID
131 func (store *WalletStore) DeleteUnconfirmedTransaction(txID string) {
132         store.DB.Delete(calcUnconfirmedTxKey(txID))
133 }
134
135 // SetGlobalTransactionIndex set global tx index by blockhash and position
136 func (store *WalletStore) SetGlobalTransactionIndex(globalTxID string, blockHash *bc.Hash, position uint64) {
137         store.DB.Set(calcGlobalTxIndexKey(globalTxID), calcGlobalTxIndex(blockHash, position))
138 }
139
140 // GetStandardUTXO get standard utxo by id
141 func (store *WalletStore) GetStandardUTXO(outid bc.Hash) []byte {
142         return store.DB.Get(StandardUTXOKey(outid))
143 }
144
145 // GetTransaction get tx by tx index
146 func (store *WalletStore) GetTransaction(txID string) ([]byte, error) {
147         formatKey := store.DB.Get(calcTxIndexKey(txID))
148         if formatKey == nil {
149                 return nil, errAccntTxIDNotFound
150         }
151         txInfo := store.DB.Get(calcAnnotatedKey(string(formatKey)))
152         return txInfo, nil
153 }
154
155 // GetGlobalTransaction get global tx by txID
156 func (store *WalletStore) GetGlobalTransaction(txID string) []byte {
157         return store.DB.Get(calcGlobalTxIndexKey(txID))
158 }
159
160 // GetTransactions get all walletDB transactions
161 func (store *WalletStore) GetTransactions() ([]*query.AnnotatedTx, error) {
162         annotatedTxs := []*query.AnnotatedTx{}
163
164         txIter := store.DB.IteratorPrefix([]byte(TxPrefix))
165         defer txIter.Release()
166         for txIter.Next() {
167                 annotatedTx := &query.AnnotatedTx{}
168                 if err := json.Unmarshal(txIter.Value(), &annotatedTx); err != nil {
169                         return nil, err
170                 }
171                 annotatedTxs = append(annotatedTxs, annotatedTx)
172         }
173
174         return annotatedTxs, nil
175 }
176
177 // GetUnconfirmedTransactions get all unconfirmed txs
178 func (store *WalletStore) GetUnconfirmedTransactions() ([]*query.AnnotatedTx, error) {
179         annotatedTxs := []*query.AnnotatedTx{}
180         txIter := store.DB.IteratorPrefix([]byte(UnconfirmedTxPrefix))
181         defer txIter.Release()
182
183         for txIter.Next() {
184                 annotatedTx := &query.AnnotatedTx{}
185                 if err := json.Unmarshal(txIter.Value(), &annotatedTx); err != nil {
186                         return nil, err
187                 }
188                 annotatedTxs = append(annotatedTxs, annotatedTx)
189         }
190         return annotatedTxs, nil
191 }
192
193 // GetUnconfirmedTransaction get unconfirmed tx by txID
194 func (store *WalletStore) GetUnconfirmedTransaction(txID string) []byte {
195         return store.DB.Get(calcUnconfirmedTxKey(txID))
196 }
197
198 // SetUnconfirmedTransaction set unconfirmed tx by txID
199 func (store *WalletStore) SetUnconfirmedTransaction(txID string, rawTx []byte) {
200         store.DB.Set(calcUnconfirmedTxKey(txID), rawTx)
201 }
202
203 // DeleteStardardUTXO delete stardard utxo by outputID
204 func (store *WalletStore) DeleteStardardUTXO(outputID bc.Hash) {
205         store.DB.Delete(StandardUTXOKey(outputID))
206 }
207
208 // DeleteContractUTXO delete contract utxo by outputID
209 func (store *WalletStore) DeleteContractUTXO(outputID bc.Hash) {
210         store.DB.Delete(ContractUTXOKey(outputID))
211 }
212
213 // SetStandardUTXO set standard utxo
214 func (store *WalletStore) SetStandardUTXO(outputID bc.Hash, data []byte) {
215         store.DB.Set(StandardUTXOKey(outputID), data)
216 }
217
218 // SetContractUTXO set standard utxo
219 func (store *WalletStore) SetContractUTXO(outputID bc.Hash, data []byte) {
220         store.DB.Set(ContractUTXOKey(outputID), data)
221 }
222
223 // GetWalletInfo get wallet information
224 func (store *WalletStore) GetWalletInfo() []byte {
225         return store.DB.Get(walletKey)
226 }
227
228 // SetWalletInfo get wallet information
229 func (store *WalletStore) SetWalletInfo(rawWallet []byte) {
230         store.DB.Set(walletKey, rawWallet)
231 }
232
233 // DeleteWalletTransactions delete all txs in wallet
234 func (store *WalletStore) DeleteWalletTransactions() {
235         batch := store.DB.NewBatch()
236
237         txIter := store.DB.IteratorPrefix([]byte(TxPrefix))
238         defer txIter.Release()
239
240         for txIter.Next() {
241                 batch.Delete(txIter.Key())
242         }
243
244         txIndexIter := store.DB.IteratorPrefix([]byte(TxIndexPrefix))
245         defer txIndexIter.Release()
246
247         for txIndexIter.Next() {
248                 batch.Delete(txIndexIter.Key())
249         }
250
251         batch.Write()
252 }
253
254 // DeleteWalletUTXOs delete all txs in wallet
255 func (store *WalletStore) DeleteWalletUTXOs() {
256         batch := store.DB.NewBatch()
257         ruIter := store.DB.IteratorPrefix([]byte(account.UTXOPreFix))
258         defer ruIter.Release()
259         for ruIter.Next() {
260                 batch.Delete(ruIter.Key())
261         }
262
263         suIter := store.DB.IteratorPrefix([]byte(account.SUTXOPrefix))
264         defer suIter.Release()
265         for suIter.Next() {
266                 batch.Delete(suIter.Key())
267         }
268         batch.Write()
269 }
270
271 // GetAccountUTXOs get all account unspent outputs
272 func (store *WalletStore) GetAccountUTXOs(key string) [][]byte {
273         accountUtxoIter := store.DB.IteratorPrefix([]byte(key))
274         defer accountUtxoIter.Release()
275
276         rawUTXOs := make([][]byte, 0)
277         for accountUtxoIter.Next() {
278                 utxo := accountUtxoIter.Value()
279                 rawUTXOs = append(rawUTXOs, utxo)
280         }
281         return rawUTXOs
282 }
283
284 // SetRecoveryStatus set recovery status
285 func (store *WalletStore) SetRecoveryStatus(recoveryKey, rawStatus []byte) {
286         store.DB.Set(recoveryKey, rawStatus)
287 }
288
289 // DeleteRecoveryStatus delete recovery status
290 func (store *WalletStore) DeleteRecoveryStatus(recoveryKey []byte) {
291         store.DB.Delete(recoveryKey)
292 }
293
294 // GetRecoveryStatus delete recovery status
295 func (store *WalletStore) GetRecoveryStatus(recoveryKey []byte) []byte {
296         return store.DB.Get(recoveryKey)
297 }