OSDN Git Service

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