Golang implemented sidechain for Bytom
Revision | 612fd76a9bfb8c36846adf00be4737914c094cbf (tree) |
---|---|
Zeit | 2019-06-23 21:40:03 |
Autor | Chengcheng Zhang <943420582@qq.c...> |
Commiter | Chengcheng Zhang |
add account_store.go
@@ -0,0 +1,251 @@ | ||
1 | +package account | |
2 | + | |
3 | +import ( | |
4 | + "encoding/json" | |
5 | + "strings" | |
6 | + | |
7 | + log "github.com/sirupsen/logrus" | |
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 | +// AccountStorer interface contains account storage functions. | |
15 | +type AccountStorer interface { | |
16 | + SetAccount(string, string, []byte) | |
17 | + SetAccountIndex([]chainkd.XPub, uint64) | |
18 | + GetAccountByAccountAlias(string) []byte | |
19 | + GetAccountByAccountID(string) []byte // duplicate in WalletStorer | |
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 | + DeleteAccountUTXOs(string) error | |
28 | + GetCoinbaseArbitrary() []byte | |
29 | + SetCoinbaseArbitrary([]byte) | |
30 | + GetMiningAddress() []byte | |
31 | + GetFirstAccount() (*Account, error) | |
32 | + SetMiningAddress([]byte) | |
33 | + GetBip44ContractIndex(string, bool) []byte | |
34 | + GetRawProgram(common.Hash) []byte // duplicate in WalletStorer | |
35 | + GetAccounts(string) ([]*Account, error) | |
36 | + GetControlPrograms() ([]*CtrlProgram, error) | |
37 | + SetRawProgram(common.Hash, []byte) | |
38 | + SetContractIndex(string, uint64) | |
39 | + SetBip44ContractIndex(string, bool, uint64) | |
40 | + GetUTXOs(string) []*UTXO | |
41 | + GetStandardUTXO(bc.Hash) []byte // duplicate in WalletStorer | |
42 | + GetContractUTXO(bc.Hash) []byte | |
43 | +} | |
44 | + | |
45 | +// AccountStore satisfies AccountStorer interface. | |
46 | +type AccountStore struct { | |
47 | + DB dbm.DB | |
48 | +} | |
49 | + | |
50 | +// NewAccountStore create new AccountStore. | |
51 | +func NewAccountStore(db dbm.DB) *AccountStore { | |
52 | + return &AccountStore{ | |
53 | + DB: db, | |
54 | + } | |
55 | +} | |
56 | + | |
57 | +// SetAccount set account account ID, account alias and raw account. | |
58 | +func (store *AccountStore) SetAccount(accountID, accountAlias string, rawAccount []byte) { | |
59 | + batch := store.DB.NewBatch() | |
60 | + batch.Set(Key(accountID), rawAccount) | |
61 | + batch.Set(aliasKey(accountAlias), []byte(accountID)) | |
62 | + batch.Write() | |
63 | +} | |
64 | + | |
65 | +// SetAccountIndex set account index | |
66 | +func (store *AccountStore) SetAccountIndex(xpubs []chainkd.XPub, keyIndex uint64) { | |
67 | + store.DB.Set(GetAccountIndexKey(xpubs), common.Unit64ToBytes(keyIndex)) | |
68 | +} | |
69 | + | |
70 | +// GetAccountByAccountAlias get account by account alias | |
71 | +func (store *AccountStore) GetAccountByAccountAlias(accountAlias string) []byte { | |
72 | + return store.DB.Get(aliasKey(accountAlias)) | |
73 | +} | |
74 | + | |
75 | +// GetAccountByAccountID get account by accountID | |
76 | +func (store *AccountStore) GetAccountByAccountID(accountID string) []byte { | |
77 | + return store.DB.Get(Key(accountID)) | |
78 | +} | |
79 | + | |
80 | +// GetAccountIndex get account index by account xpubs | |
81 | +func (store *AccountStore) GetAccountIndex(xpubs []chainkd.XPub) []byte { | |
82 | + return store.DB.Get(GetAccountIndexKey(xpubs)) | |
83 | +} | |
84 | + | |
85 | +// DeleteAccountByAccountAlias delete account by account alias | |
86 | +func (store *AccountStore) DeleteAccountByAccountAlias(accountAlias string) { | |
87 | + store.DB.Delete(aliasKey(accountAlias)) | |
88 | +} | |
89 | + | |
90 | +// DeleteAccountByAccountID delete account by accountID | |
91 | +func (store *AccountStore) DeleteAccountByAccountID(accountID string) { | |
92 | + store.DB.Delete(Key(accountID)) | |
93 | +} | |
94 | + | |
95 | +// DeleteRawProgram delete raw control program by hash | |
96 | +func (store *AccountStore) DeleteRawProgram(hash common.Hash) { | |
97 | + store.DB.Delete(ContractKey(hash)) | |
98 | +} | |
99 | + | |
100 | +// DeleteBip44ContractIndex delete bip44 contract index by accountID | |
101 | +func (store *AccountStore) DeleteBip44ContractIndex(accountID string) { | |
102 | + batch := store.DB.NewBatch() | |
103 | + batch.Delete(bip44ContractIndexKey(accountID, false)) | |
104 | + batch.Delete(bip44ContractIndexKey(accountID, true)) | |
105 | + batch.Write() | |
106 | +} | |
107 | + | |
108 | +// DeleteContractIndex delete contract index by accountID | |
109 | +func (store *AccountStore) DeleteContractIndex(accountID string) { | |
110 | + store.DB.Delete(contractIndexKey(accountID)) | |
111 | +} | |
112 | + | |
113 | +// GetContractIndex get contract index | |
114 | +func (store *AccountStore) GetContractIndex(accountID string) []byte { | |
115 | + return store.DB.Get(contractIndexKey(accountID)) | |
116 | +} | |
117 | + | |
118 | +// DeleteAccountUTXOs delete account utxos by accountID | |
119 | +func (store *AccountStore) DeleteAccountUTXOs(accountID string) error { | |
120 | + accountUtxoIter := store.DB.IteratorPrefix([]byte(UTXOPreFix)) | |
121 | + defer accountUtxoIter.Release() | |
122 | + for accountUtxoIter.Next() { | |
123 | + accountUtxo := &UTXO{} | |
124 | + if err := json.Unmarshal(accountUtxoIter.Value(), accountUtxo); err != nil { | |
125 | + return err | |
126 | + } | |
127 | + | |
128 | + if accountID == accountUtxo.AccountID { | |
129 | + store.DB.Delete(StandardUTXOKey(accountUtxo.OutputID)) | |
130 | + } | |
131 | + } | |
132 | + return nil | |
133 | +} | |
134 | + | |
135 | +// GetCoinbaseArbitrary get coinbase arbitrary | |
136 | +func (store *AccountStore) GetCoinbaseArbitrary() []byte { | |
137 | + return store.DB.Get(CoinbaseAbKey) | |
138 | +} | |
139 | + | |
140 | +// SetCoinbaseArbitrary set coinbase arbitrary | |
141 | +func (store *AccountStore) SetCoinbaseArbitrary(arbitrary []byte) { | |
142 | + store.DB.Set(CoinbaseAbKey, arbitrary) | |
143 | +} | |
144 | + | |
145 | +// GetMiningAddress get mining address | |
146 | +func (store *AccountStore) GetMiningAddress() []byte { | |
147 | + return store.DB.Get(miningAddressKey) | |
148 | +} | |
149 | + | |
150 | +// GetFirstAccount get first account | |
151 | +func (store *AccountStore) GetFirstAccount() (*Account, error) { | |
152 | + accountIter := store.DB.IteratorPrefix([]byte(accountPrefix)) | |
153 | + defer accountIter.Release() | |
154 | + if !accountIter.Next() { | |
155 | + return nil, ErrFindAccount | |
156 | + } | |
157 | + | |
158 | + account := &Account{} | |
159 | + if err := json.Unmarshal(accountIter.Value(), account); err != nil { | |
160 | + return nil, err | |
161 | + } | |
162 | + return account, nil | |
163 | +} | |
164 | + | |
165 | +// SetMiningAddress set mining address | |
166 | +func (store *AccountStore) SetMiningAddress(rawProgram []byte) { | |
167 | + store.DB.Set(miningAddressKey, rawProgram) | |
168 | +} | |
169 | + | |
170 | +// GetBip44ContractIndex get bip44 contract index | |
171 | +func (store *AccountStore) GetBip44ContractIndex(accountID string, change bool) []byte { | |
172 | + return store.DB.Get(bip44ContractIndexKey(accountID, change)) | |
173 | +} | |
174 | + | |
175 | +// GetRawProgram get raw control program | |
176 | +func (store *AccountStore) GetRawProgram(hash common.Hash) []byte { | |
177 | + return store.DB.Get(ContractKey(hash)) | |
178 | +} | |
179 | + | |
180 | +// GetAccounts get all accounts which name prfix is id. | |
181 | +func (store *AccountStore) GetAccounts(id string) ([]*Account, error) { | |
182 | + accounts := []*Account{} | |
183 | + accountIter := store.DB.IteratorPrefix(Key(strings.TrimSpace(id))) | |
184 | + defer accountIter.Release() | |
185 | + | |
186 | + for accountIter.Next() { | |
187 | + account := &Account{} | |
188 | + if err := json.Unmarshal(accountIter.Value(), &account); err != nil { | |
189 | + return nil, err | |
190 | + } | |
191 | + accounts = append(accounts, account) | |
192 | + } | |
193 | + return accounts, nil | |
194 | +} | |
195 | + | |
196 | +// GetControlPrograms get all local control programs | |
197 | +func (store *AccountStore) GetControlPrograms() ([]*CtrlProgram, error) { | |
198 | + cps := []*CtrlProgram{} | |
199 | + cpIter := store.DB.IteratorPrefix(contractPrefix) | |
200 | + defer cpIter.Release() | |
201 | + | |
202 | + for cpIter.Next() { | |
203 | + cp := &CtrlProgram{} | |
204 | + if err := json.Unmarshal(cpIter.Value(), cp); err != nil { | |
205 | + return nil, err | |
206 | + } | |
207 | + cps = append(cps, cp) | |
208 | + } | |
209 | + return cps, nil | |
210 | +} | |
211 | + | |
212 | +// SetRawProgram set raw program | |
213 | +func (store *AccountStore) SetRawProgram(hash common.Hash, program []byte) { | |
214 | + store.DB.Set(ContractKey(hash), program) | |
215 | +} | |
216 | + | |
217 | +// SetContractIndex set contract index | |
218 | +func (store *AccountStore) SetContractIndex(accountID string, index uint64) { | |
219 | + store.DB.Set(contractIndexKey(accountID), common.Unit64ToBytes(index)) | |
220 | +} | |
221 | + | |
222 | +// SetBip44ContractIndex set contract index | |
223 | +func (store *AccountStore) SetBip44ContractIndex(accountID string, change bool, index uint64) { | |
224 | + store.DB.Set(bip44ContractIndexKey(accountID, change), common.Unit64ToBytes(index)) | |
225 | +} | |
226 | + | |
227 | +// GetUTXOs get utxos by accountID | |
228 | +func (store *AccountStore) GetUTXOs(accountID string) []*UTXO { | |
229 | + utxos := []*UTXO{} | |
230 | + utxoIter := store.DB.IteratorPrefix([]byte(UTXOPreFix)) | |
231 | + defer utxoIter.Release() | |
232 | + for utxoIter.Next() { | |
233 | + u := &UTXO{} | |
234 | + if err := json.Unmarshal(utxoIter.Value(), u); err != nil { | |
235 | + log.WithFields(log.Fields{"module": logModule, "err": err}).Error("utxoKeeper findUtxos fail on unmarshal utxo") | |
236 | + continue | |
237 | + } | |
238 | + utxos = append(utxos, u) | |
239 | + } | |
240 | + return utxos | |
241 | +} | |
242 | + | |
243 | +// GetStandardUTXO get standard utxo by id | |
244 | +func (store *AccountStore) GetStandardUTXO(outid bc.Hash) []byte { | |
245 | + return store.DB.Get(StandardUTXOKey(outid)) | |
246 | +} | |
247 | + | |
248 | +// GetContractUTXO get contract utxo | |
249 | +func (store *AccountStore) GetContractUTXO(outid bc.Hash) []byte { | |
250 | + return store.DB.Get(ContractUTXOKey(outid)) | |
251 | +} |
@@ -39,10 +39,10 @@ var ( | ||
39 | 39 | accountIndexPrefix = []byte("AccountIndex:") |
40 | 40 | accountPrefix = []byte("Account:") |
41 | 41 | aliasPrefix = []byte("AccountAlias:") |
42 | - contractIndexPrefix = []byte("ContractIndex") | |
42 | + contractIndexPrefix = []byte("ContractIndex:") | |
43 | 43 | contractPrefix = []byte("Contract:") |
44 | - miningAddressKey = []byte("MiningAddress") | |
45 | - CoinbaseAbKey = []byte("CoinbaseArbitrary") | |
44 | + miningAddressKey = []byte("MiningAddress:") | |
45 | + CoinbaseAbKey = []byte("CoinbaseArbitrary:") | |
46 | 46 | ) |
47 | 47 | |
48 | 48 | // pre-define errors for supporting bytom errorFormatter |
@@ -27,6 +27,7 @@ func (m *Manager) Backup() (*Image, error) { | ||
27 | 27 | Slice: []*ImageSlice{}, |
28 | 28 | } |
29 | 29 | |
30 | + // GetAccounts() | |
30 | 31 | accountIter := m.db.IteratorPrefix(accountPrefix) |
31 | 32 | defer accountIter.Release() |
32 | 33 | for accountIter.Next() { |
@@ -121,7 +121,7 @@ func getAccountFromACP(program []byte, store WalletStorer) (*account.Account, er | ||
121 | 121 | return nil, err |
122 | 122 | } |
123 | 123 | |
124 | - accountValue := store.GetAccount(accountCP.AccountID) | |
124 | + accountValue := store.GetAccountByAccountID(accountCP.AccountID) | |
125 | 125 | if accountValue == nil { |
126 | 126 | return nil, fmt.Errorf("failed get account:%s ", accountCP.AccountID) |
127 | 127 | } |
@@ -613,7 +613,7 @@ func TestStateForScope(t *testing.T) { | ||
613 | 613 | } |
614 | 614 | |
615 | 615 | func bip44ContractIndexKey(accountID string, change bool) []byte { |
616 | - contractIndexPrefix := []byte("ContractIndex") | |
616 | + contractIndexPrefix := []byte("ContractIndex:") | |
617 | 617 | key := append(contractIndexPrefix, accountID...) |
618 | 618 | if change { |
619 | 619 | return append(key, []byte{1}...) |
@@ -17,7 +17,7 @@ type WalletStorer interface { | ||
17 | 17 | GetAssetDefinition(*bc.AssetID) []byte |
18 | 18 | SetAssetDefinition(*bc.AssetID, []byte) |
19 | 19 | GetRawProgram(common.Hash) []byte |
20 | - GetAccount(string) []byte | |
20 | + GetAccountByAccountID(string) []byte | |
21 | 21 | DeleteTransaction(uint64) |
22 | 22 | SetTransaction(uint64, uint32, string, []byte) |
23 | 23 | DeleteUnconfirmedTransaction(string) |
@@ -71,7 +71,7 @@ func (store *WalletStore) GetRawProgram(hash common.Hash) []byte { | ||
71 | 71 | } |
72 | 72 | |
73 | 73 | // GetAccount get account value by account ID |
74 | -func (store *WalletStore) GetAccount(accountID string) []byte { | |
74 | +func (store *WalletStore) GetAccountByAccountID(accountID string) []byte { | |
75 | 75 | return store.DB.Get(account.Key(accountID)) |
76 | 76 | } |
77 | 77 |