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"
12 // AccountStorer interface contains account storage functions.
13 type AccountStorer interface {
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)
42 GetStandardUTXO(bc.Hash) []byte
43 GetContractUTXO(bc.Hash) []byte
44 SetStandardUTXO(bc.Hash, []byte)
47 // AccountStore satisfies AccountStorer interface.
48 type AccountStore struct {
53 // NewAccountStore create new AccountStore.
54 func NewAccountStore(db dbm.DB) *AccountStore {
61 // InitBatch initial batch
62 func (store *AccountStore) InitBatch() {
63 if store.batch == nil {
64 store.batch = store.accountDB.NewBatch()
68 // CommitBatch commit batch
69 func (store *AccountStore) CommitBatch() {
70 if store.batch != nil {
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 {
82 batch.Set(AccountIDKey(accountID), rawAccount)
83 batch.Set(AccountAliasKey(accountAlias), []byte(accountID))
84 if store.batch == nil {
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 {
95 batch.Delete(AccountIDKey(accountID))
96 batch.Delete(AccountAliasKey(accountAlias))
97 if store.batch == nil {
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))
107 store.batch.Set(AccountIndexKey(xpubs), common.Unit64ToBytes(keyIndex))
111 // GetAccountByAccountAlias get account by account alias
112 func (store *AccountStore) GetAccountByAccountAlias(accountAlias string) []byte {
113 return store.accountDB.Get(AccountAliasKey(accountAlias))
116 // GetAccountByAccountID get account by accountID
117 func (store *AccountStore) GetAccountByAccountID(accountID string) []byte {
118 return store.accountDB.Get(AccountIDKey(accountID))
121 // GetAccountIndex get account index by account xpubs
122 func (store *AccountStore) GetAccountIndex(xpubs []chainkd.XPub) []byte {
123 return store.accountDB.Get(AccountIndexKey(xpubs))
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))
131 store.batch.Delete(AccountAliasKey(accountAlias))
135 // DeleteAccountByAccountID delete account by accountID
136 func (store *AccountStore) DeleteAccountByAccountID(accountID string) {
137 if store.batch == nil {
138 store.accountDB.Delete(AccountIDKey(accountID))
140 store.batch.Delete(AccountIDKey(accountID))
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))
149 store.batch.Delete(ContractKey(hash))
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 {
159 batch.Delete(Bip44ContractIndexKey(accountID, false))
160 batch.Delete(Bip44ContractIndexKey(accountID, true))
161 if store.batch == nil {
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))
171 store.batch.Delete(ContractIndexKey(accountID))
175 // GetContractIndex get contract index
176 func (store *AccountStore) GetContractIndex(accountID string) []byte {
177 return store.accountDB.Get(ContractIndexKey(accountID))
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()
185 utxos := make([][]byte, 0)
186 for accountUtxoIter.Next() {
187 utxos = append(utxos, accountUtxoIter.Value())
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))
197 store.batch.Delete(StandardUTXOKey(outputID))
201 // GetCoinbaseArbitrary get coinbase arbitrary
202 func (store *AccountStore) GetCoinbaseArbitrary() []byte {
203 return store.accountDB.Get([]byte(CoinbaseAbKey))
206 // SetCoinbaseArbitrary set coinbase arbitrary
207 func (store *AccountStore) SetCoinbaseArbitrary(arbitrary []byte) {
208 if store.batch == nil {
209 store.accountDB.Set([]byte(CoinbaseAbKey), arbitrary)
211 store.batch.Set([]byte(CoinbaseAbKey), arbitrary)
215 // GetMiningAddress get mining address
216 func (store *AccountStore) GetMiningAddress() []byte {
217 return store.accountDB.Get([]byte(MiningAddressKey))
220 // GetFirstAccount get first account
221 func (store *AccountStore) GetFirstAccount() ([]byte, error) {
222 accountIter := store.accountDB.IteratorPrefix([]byte(AccountPrefix))
223 defer accountIter.Release()
225 if !accountIter.Next() {
226 return nil, ErrFindAccount
228 return accountIter.Value(), nil
231 // SetMiningAddress set mining address
232 func (store *AccountStore) SetMiningAddress(rawProgram []byte) {
233 if store.batch == nil {
234 store.accountDB.Set([]byte(MiningAddressKey), rawProgram)
236 store.batch.Set([]byte(MiningAddressKey), rawProgram)
240 // GetBip44ContractIndex get bip44 contract index
241 func (store *AccountStore) GetBip44ContractIndex(accountID string, change bool) []byte {
242 return store.accountDB.Get(Bip44ContractIndexKey(accountID, change))
245 // GetRawProgram get raw control program
246 func (store *AccountStore) GetRawProgram(hash common.Hash) []byte {
247 return store.accountDB.Get(ContractKey(hash))
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()
255 accounts := make([][]byte, 0)
256 for accountIter.Next() {
257 accounts = append(accounts, accountIter.Value())
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()
267 cps := make([][]byte, 0)
269 cps = append(cps, cpIter.Value())
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)
279 store.batch.Set(ContractKey(hash), program)
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))
288 store.batch.Set(ContractIndexKey(accountID), common.Unit64ToBytes(index))
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))
297 store.batch.Set(Bip44ContractIndexKey(accountID, change), common.Unit64ToBytes(index))
301 // GetUTXOs get utxos by accountID
302 func (store *AccountStore) GetUTXOs() [][]byte {
303 utxoIter := store.accountDB.IteratorPrefix([]byte(UTXOPrefix))
304 defer utxoIter.Release()
306 utxos := make([][]byte, 0)
307 for utxoIter.Next() {
308 utxos = append(utxos, utxoIter.Value())
313 // GetStandardUTXO get standard utxo by id
314 func (store *AccountStore) GetStandardUTXO(outid bc.Hash) []byte {
315 return store.accountDB.Get(StandardUTXOKey(outid))
318 // GetContractUTXO get contract utxo
319 func (store *AccountStore) GetContractUTXO(outid bc.Hash) []byte {
320 return store.accountDB.Get(ContractUTXOKey(outid))
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)
328 store.batch.Set(StandardUTXOKey(outputID), data)