Golang implemented sidechain for Bytom
リビジョン | 25dc665492fefc26e896f21fcf43ea8000428380 (tree) |
---|---|
日時 | 2019-06-26 00:19:06 |
作者 | Chengcheng Zhang <943420582@qq.c...> |
コミッター | Chengcheng Zhang |
finish account
@@ -67,7 +67,7 @@ type CtrlProgram struct { | ||
67 | 67 | |
68 | 68 | // Manager stores accounts and their associated control programs. |
69 | 69 | type Manager struct { |
70 | - db dbm.DB | |
70 | + store database.AccountStorer | |
71 | 71 | chain *protocol.Chain |
72 | 72 | utxoKeeper *utxoKeeper |
73 | 73 |
@@ -83,11 +83,12 @@ type Manager struct { | ||
83 | 83 | } |
84 | 84 | |
85 | 85 | // NewManager creates a new account manager |
86 | -func NewManager(walletDB dbm.DB, chain *protocol.Chain) *Manager { | |
86 | +func NewManager(accountdb dbm.DB, chain *protocol.Chain) *Manager { | |
87 | + store := database.NewAccountStore(accountdb) | |
87 | 88 | return &Manager{ |
88 | - db: walletDB, | |
89 | + store: store, | |
89 | 90 | chain: chain, |
90 | - utxoKeeper: newUtxoKeeper(chain.BestBlockHeight, walletDB), | |
91 | + utxoKeeper: newUtxoKeeper(chain.BestBlockHeight, store), | |
91 | 92 | cache: lru.New(maxAccountCache), |
92 | 93 | aliasCache: lru.New(maxAccountCache), |
93 | 94 | delayedACPs: make(map[*txbuilder.TemplateBuilder][]*CtrlProgram), |
@@ -120,13 +121,14 @@ func (m *Manager) saveAccount(account *Account, updateIndex bool) error { | ||
120 | 121 | return ErrMarshalAccount |
121 | 122 | } |
122 | 123 | |
123 | - storeBatch := m.db.NewBatch() | |
124 | - storeBatch.Set(database.AccountIDKey(account.ID), rawAccount) | |
125 | - storeBatch.Set(database.AccountAliasKey(account.Alias), []byte(account.ID)) | |
124 | + m.store.InitBatch() | |
125 | + defer m.store.CommitBatch() | |
126 | + | |
127 | + m.store.SetAccount(account.ID, account.Alias, rawAccount) | |
126 | 128 | if updateIndex { |
127 | - storeBatch.Set(database.AccountIndexKey(account.XPubs), common.Unit64ToBytes(account.KeyIndex)) | |
129 | + m.store.SetAccountIndex(account.XPubs, account.KeyIndex) | |
128 | 130 | } |
129 | - storeBatch.Write() | |
131 | + | |
130 | 132 | return nil |
131 | 133 | } |
132 | 134 |
@@ -135,7 +137,7 @@ func (m *Manager) SaveAccount(account *Account) error { | ||
135 | 137 | m.accountMu.Lock() |
136 | 138 | defer m.accountMu.Unlock() |
137 | 139 | |
138 | - if existed := m.db.Get(database.AccountAliasKey(account.Alias)); existed != nil { | |
140 | + if existed := m.store.GetAccountByAccountAlias(account.Alias); existed != nil { | |
139 | 141 | return ErrDuplicateAlias |
140 | 142 | } |
141 | 143 |
@@ -149,7 +151,7 @@ func (m *Manager) SaveAccount(account *Account) error { | ||
149 | 151 | } |
150 | 152 | |
151 | 153 | currentIndex := uint64(0) |
152 | - if rawIndexBytes := m.db.Get(database.AccountIndexKey(account.XPubs)); rawIndexBytes != nil { | |
154 | + if rawIndexBytes := m.store.GetAccountIndex(account.XPubs); rawIndexBytes != nil { | |
153 | 155 | currentIndex = common.BytesToUnit64(rawIndexBytes) |
154 | 156 | } |
155 | 157 | return m.saveAccount(account, account.KeyIndex > currentIndex) |
@@ -160,12 +162,12 @@ func (m *Manager) Create(xpubs []chainkd.XPub, quorum int, alias string, deriveR | ||
160 | 162 | m.accountMu.Lock() |
161 | 163 | defer m.accountMu.Unlock() |
162 | 164 | |
163 | - if existed := m.db.Get(database.AccountAliasKey(alias)); existed != nil { | |
165 | + if existed := m.store.GetAccountByAccountAlias(alias); existed != nil { | |
164 | 166 | return nil, ErrDuplicateAlias |
165 | 167 | } |
166 | 168 | |
167 | 169 | acctIndex := uint64(1) |
168 | - if rawIndexBytes := m.db.Get(database.AccountIndexKey(xpubs)); rawIndexBytes != nil { | |
170 | + if rawIndexBytes := m.store.GetAccountIndex(xpubs); rawIndexBytes != nil { | |
169 | 171 | acctIndex = common.BytesToUnit64(rawIndexBytes) + 1 |
170 | 172 | } |
171 | 173 | account, err := CreateAccount(xpubs, quorum, alias, acctIndex, deriveRule) |
@@ -191,7 +193,7 @@ func (m *Manager) UpdateAccountAlias(accountID string, newAlias string) (err err | ||
191 | 193 | oldAlias := account.Alias |
192 | 194 | |
193 | 195 | normalizedAlias := strings.ToLower(strings.TrimSpace(newAlias)) |
194 | - if existed := m.db.Get(database.AccountAliasKey(normalizedAlias)); existed != nil { | |
196 | + if existed := m.store.GetAccountByAccountAlias(normalizedAlias); existed != nil { | |
195 | 197 | return ErrDuplicateAlias |
196 | 198 | } |
197 | 199 |
@@ -205,11 +207,12 @@ func (m *Manager) UpdateAccountAlias(accountID string, newAlias string) (err err | ||
205 | 207 | return ErrMarshalAccount |
206 | 208 | } |
207 | 209 | |
208 | - storeBatch := m.db.NewBatch() | |
209 | - storeBatch.Delete(database.AccountAliasKey(oldAlias)) | |
210 | - storeBatch.Set(database.AccountIDKey(accountID), rawAccount) | |
211 | - storeBatch.Set(database.AccountAliasKey(normalizedAlias), []byte(accountID)) | |
212 | - storeBatch.Write() | |
210 | + m.store.InitBatch() | |
211 | + defer m.store.CommitBatch() | |
212 | + | |
213 | + m.store.DeleteAccountByAccountAlias(oldAlias) | |
214 | + m.store.SetAccount(accountID, normalizedAlias, rawAccount) | |
215 | + | |
213 | 216 | return nil |
214 | 217 | } |
215 | 218 |
@@ -276,29 +279,30 @@ func (m *Manager) deleteAccountControlPrograms(accountID string) error { | ||
276 | 279 | for _, cp := range cps { |
277 | 280 | if cp.AccountID == accountID { |
278 | 281 | sha3pool.Sum256(hash[:], cp.ControlProgram) |
279 | - m.db.Delete(database.ContractKey(hash)) | |
282 | + m.store.DeleteRawProgram(hash) | |
280 | 283 | } |
281 | 284 | } |
282 | - m.db.Delete(database.Bip44ContractIndexKey(accountID, false)) | |
283 | - m.db.Delete(database.Bip44ContractIndexKey(accountID, true)) | |
284 | - m.db.Delete(database.ContractIndexKey(accountID)) | |
285 | + | |
286 | + m.store.DeleteBip44ContractIndex(accountID) | |
287 | + m.store.DeleteContractIndex(accountID) | |
288 | + | |
285 | 289 | return nil |
286 | 290 | } |
287 | 291 | |
288 | 292 | // deleteAccountUtxos deletes utxos matching accountID |
289 | 293 | func (m *Manager) deleteAccountUtxos(accountID string) error { |
290 | - accountUtxoIter := m.db.IteratorPrefix([]byte(UTXOPreFix)) | |
291 | - defer accountUtxoIter.Release() | |
292 | - for accountUtxoIter.Next() { | |
293 | - accountUtxo := &UTXO{} | |
294 | - if err := json.Unmarshal(accountUtxoIter.Value(), accountUtxo); err != nil { | |
294 | + rawUTXOs := m.store.GetAccountUTXOs(accountID) | |
295 | + | |
296 | + for _, rawUTXO := range rawUTXOs { | |
297 | + utxo := new(UTXO) | |
298 | + if err := json.Unmarshal(rawUTXO, utxo); err != nil { | |
295 | 299 | return err |
296 | 300 | } |
297 | - | |
298 | - if accountID == accountUtxo.AccountID { | |
299 | - m.db.Delete(StandardUTXOKey(accountUtxo.OutputID)) | |
301 | + if accountID == utxo.AccountID { | |
302 | + m.store.DeleteUTXO(utxo.OutputID) | |
300 | 303 | } |
301 | 304 | } |
305 | + | |
302 | 306 | return nil |
303 | 307 | } |
304 | 308 |
@@ -323,10 +327,11 @@ func (m *Manager) DeleteAccount(accountID string) (err error) { | ||
323 | 327 | m.aliasCache.Remove(account.Alias) |
324 | 328 | m.cacheMu.Unlock() |
325 | 329 | |
326 | - storeBatch := m.db.NewBatch() | |
327 | - storeBatch.Delete(database.AccountAliasKey(account.Alias)) | |
328 | - storeBatch.Delete(database.AccountIDKey(account.ID)) | |
329 | - storeBatch.Write() | |
330 | + m.store.InitBatch() | |
331 | + defer m.store.CommitBatch() | |
332 | + | |
333 | + m.store.DeleteAccountByAccountAlias(account.Alias) | |
334 | + m.store.DeleteAccountByAccountID(account.ID) | |
330 | 335 | return nil |
331 | 336 | } |
332 | 337 |
@@ -339,7 +344,7 @@ func (m *Manager) FindByAlias(alias string) (*Account, error) { | ||
339 | 344 | return m.FindByID(cachedID.(string)) |
340 | 345 | } |
341 | 346 | |
342 | - rawID := m.db.Get(database.AccountAliasKey(alias)) | |
347 | + rawID := m.store.GetAccountByAccountAlias(alias) | |
343 | 348 | if rawID == nil { |
344 | 349 | return nil, ErrFindAccount |
345 | 350 | } |
@@ -360,7 +365,7 @@ func (m *Manager) FindByID(id string) (*Account, error) { | ||
360 | 365 | return cachedAccount.(*Account), nil |
361 | 366 | } |
362 | 367 | |
363 | - rawAccount := m.db.Get(database.AccountIDKey(id)) | |
368 | + rawAccount := m.store.GetAccountByAccountID(id) | |
364 | 369 | if rawAccount == nil { |
365 | 370 | return nil, ErrFindAccount |
366 | 371 | } |
@@ -378,7 +383,7 @@ func (m *Manager) FindByID(id string) (*Account, error) { | ||
378 | 383 | |
379 | 384 | // GetAccountByProgram return Account by given CtrlProgram |
380 | 385 | func (m *Manager) GetAccountByProgram(program *CtrlProgram) (*Account, error) { |
381 | - rawAccount := m.db.Get(database.AccountIDKey(program.AccountID)) | |
386 | + rawAccount := m.store.GetAccountByAccountID(program.AccountID) | |
382 | 387 | if rawAccount == nil { |
383 | 388 | return nil, ErrFindAccount |
384 | 389 | } |
@@ -404,7 +409,7 @@ func (m *Manager) GetAccountByXPubsIndex(xPubs []chainkd.XPub, index uint64) (*A | ||
404 | 409 | |
405 | 410 | // GetAliasByID return the account alias by given ID |
406 | 411 | func (m *Manager) GetAliasByID(id string) string { |
407 | - rawAccount := m.db.Get(database.AccountIDKey(id)) | |
412 | + rawAccount := m.store.GetAccountByAccountID(id) | |
408 | 413 | if rawAccount == nil { |
409 | 414 | log.Warn("GetAliasByID fail to find account") |
410 | 415 | return "" |
@@ -418,7 +423,7 @@ func (m *Manager) GetAliasByID(id string) string { | ||
418 | 423 | } |
419 | 424 | |
420 | 425 | func (m *Manager) GetCoinbaseArbitrary() []byte { |
421 | - if arbitrary := m.db.Get([]byte(database.CoinbaseAbKey)); arbitrary != nil { | |
426 | + if arbitrary := m.store.GetCoinbaseArbitrary(); arbitrary != nil { | |
422 | 427 | return arbitrary |
423 | 428 | } |
424 | 429 | return []byte{} |
@@ -439,19 +444,18 @@ func (m *Manager) GetCoinbaseControlProgram() ([]byte, error) { | ||
439 | 444 | |
440 | 445 | // GetCoinbaseCtrlProgram will return the coinbase CtrlProgram |
441 | 446 | func (m *Manager) GetCoinbaseCtrlProgram() (*CtrlProgram, error) { |
442 | - if data := m.db.Get([]byte(database.MiningAddressKey)); data != nil { | |
447 | + if data := m.store.GetMiningAddress(); data != nil { | |
443 | 448 | cp := &CtrlProgram{} |
444 | 449 | return cp, json.Unmarshal(data, cp) |
445 | 450 | } |
446 | 451 | |
447 | - accountIter := m.db.IteratorPrefix([]byte(database.AccountPrefix)) | |
448 | - defer accountIter.Release() | |
449 | - if !accountIter.Next() { | |
450 | - return nil, ErrFindAccount | |
452 | + fistAccount, err := m.store.GetFirstAccount() | |
453 | + if err != nil { | |
454 | + return nil, err | |
451 | 455 | } |
452 | 456 | |
453 | 457 | account := &Account{} |
454 | - if err := json.Unmarshal(accountIter.Value(), account); err != nil { | |
458 | + if err := json.Unmarshal(fistAccount, account); err != nil { | |
455 | 459 | return nil, err |
456 | 460 | } |
457 | 461 |
@@ -465,14 +469,15 @@ func (m *Manager) GetCoinbaseCtrlProgram() (*CtrlProgram, error) { | ||
465 | 469 | return nil, err |
466 | 470 | } |
467 | 471 | |
468 | - m.db.Set([]byte(database.MiningAddressKey), rawCP) | |
472 | + m.store.SetMiningAddress(rawCP) | |
473 | + | |
469 | 474 | return program, nil |
470 | 475 | } |
471 | 476 | |
472 | 477 | // GetContractIndex return the current index |
473 | 478 | func (m *Manager) GetContractIndex(accountID string) uint64 { |
474 | 479 | index := uint64(0) |
475 | - if rawIndexBytes := m.db.Get(database.ContractIndexKey(accountID)); rawIndexBytes != nil { | |
480 | + if rawIndexBytes := m.store.GetContractIndex(accountID); rawIndexBytes != nil { | |
476 | 481 | index = common.BytesToUnit64(rawIndexBytes) |
477 | 482 | } |
478 | 483 | return index |
@@ -481,7 +486,7 @@ func (m *Manager) GetContractIndex(accountID string) uint64 { | ||
481 | 486 | // GetBip44ContractIndex return the current bip44 contract index |
482 | 487 | func (m *Manager) GetBip44ContractIndex(accountID string, change bool) uint64 { |
483 | 488 | index := uint64(0) |
484 | - if rawIndexBytes := m.db.Get(database.Bip44ContractIndexKey(accountID, change)); rawIndexBytes != nil { | |
489 | + if rawIndexBytes := m.store.GetBip44ContractIndex(accountID, change); rawIndexBytes != nil { | |
485 | 490 | index = common.BytesToUnit64(rawIndexBytes) |
486 | 491 | } |
487 | 492 | return index |
@@ -496,7 +501,7 @@ func (m *Manager) GetLocalCtrlProgramByAddress(address string) (*CtrlProgram, er | ||
496 | 501 | |
497 | 502 | var hash [32]byte |
498 | 503 | sha3pool.Sum256(hash[:], program) |
499 | - rawProgram := m.db.Get(database.ContractKey(hash)) | |
504 | + rawProgram := m.store.GetRawProgram(hash) | |
500 | 505 | if rawProgram == nil { |
501 | 506 | return nil, ErrFindCtrlProgram |
502 | 507 | } |
@@ -518,40 +523,43 @@ func (m *Manager) GetMiningAddress() (string, error) { | ||
518 | 523 | func (m *Manager) IsLocalControlProgram(prog []byte) bool { |
519 | 524 | var hash common.Hash |
520 | 525 | sha3pool.Sum256(hash[:], prog) |
521 | - bytes := m.db.Get(database.ContractKey(hash)) | |
526 | + bytes := m.store.GetRawProgram(hash) | |
522 | 527 | return bytes != nil |
523 | 528 | } |
524 | 529 | |
525 | 530 | // ListAccounts will return the accounts in the db |
526 | 531 | func (m *Manager) ListAccounts(id string) ([]*Account, error) { |
527 | - accounts := []*Account{} | |
528 | - accountIter := m.db.IteratorPrefix(database.AccountIDKey(strings.TrimSpace(id))) | |
529 | - defer accountIter.Release() | |
532 | + rawAccounts := m.store.GetAccounts(id) | |
530 | 533 | |
531 | - for accountIter.Next() { | |
532 | - account := &Account{} | |
533 | - if err := json.Unmarshal(accountIter.Value(), &account); err != nil { | |
534 | + accounts := []*Account{} | |
535 | + for _, rawAccount := range rawAccounts { | |
536 | + account := new(Account) | |
537 | + if err := json.Unmarshal(rawAccount, &account); err != nil { | |
534 | 538 | return nil, err |
535 | 539 | } |
536 | 540 | accounts = append(accounts, account) |
537 | 541 | } |
542 | + | |
538 | 543 | return accounts, nil |
539 | 544 | } |
540 | 545 | |
541 | 546 | // ListControlProgram return all the local control program |
542 | 547 | func (m *Manager) ListControlProgram() ([]*CtrlProgram, error) { |
543 | - cps := []*CtrlProgram{} | |
544 | - cpIter := m.db.IteratorPrefix([]byte(database.ContractPrefix)) | |
545 | - defer cpIter.Release() | |
548 | + rawControlPrograms, err := m.store.GetControlPrograms() | |
549 | + if err != nil { | |
550 | + return nil, err | |
551 | + } | |
546 | 552 | |
547 | - for cpIter.Next() { | |
548 | - cp := &CtrlProgram{} | |
549 | - if err := json.Unmarshal(cpIter.Value(), cp); err != nil { | |
553 | + controlPrograms := []*CtrlProgram{} | |
554 | + for _, rawControlProgram := range rawControlPrograms { | |
555 | + controlProgram := new(CtrlProgram) | |
556 | + if err := json.Unmarshal(rawControlProgram, controlProgram); err != nil { | |
550 | 557 | return nil, err |
551 | 558 | } |
552 | - cps = append(cps, cp) | |
559 | + controlPrograms = append(controlPrograms, controlProgram) | |
553 | 560 | } |
554 | - return cps, nil | |
561 | + | |
562 | + return controlPrograms, nil | |
555 | 563 | } |
556 | 564 | |
557 | 565 | func (m *Manager) ListUnconfirmedUtxo(accountID string, isSmartContract bool) []*UTXO { |
@@ -586,12 +594,12 @@ func (m *Manager) SetMiningAddress(miningAddress string) (string, error) { | ||
586 | 594 | return "", err |
587 | 595 | } |
588 | 596 | |
589 | - m.db.Set([]byte(database.MiningAddressKey), rawCP) | |
597 | + m.store.SetMiningAddress(rawCP) | |
590 | 598 | return m.GetMiningAddress() |
591 | 599 | } |
592 | 600 | |
593 | 601 | func (m *Manager) SetCoinbaseArbitrary(arbitrary []byte) { |
594 | - m.db.Set([]byte(database.CoinbaseAbKey), arbitrary) | |
602 | + m.store.SetCoinbaseArbitrary(arbitrary) | |
595 | 603 | } |
596 | 604 | |
597 | 605 | // CreateCtrlProgram generate an address for the select account |
@@ -706,17 +714,18 @@ func (m *Manager) saveControlProgram(prog *CtrlProgram, updateIndex bool) error | ||
706 | 714 | return err |
707 | 715 | } |
708 | 716 | |
709 | - storeBatch := m.db.NewBatch() | |
710 | - storeBatch.Set(database.ContractKey(hash), accountCP) | |
717 | + m.store.InitBatch() | |
718 | + defer m.store.CommitBatch() | |
719 | + | |
720 | + m.store.SetRawProgram(hash, accountCP) | |
711 | 721 | if updateIndex { |
712 | 722 | switch acct.DeriveRule { |
713 | 723 | case signers.BIP0032: |
714 | - storeBatch.Set(database.ContractIndexKey(acct.ID), common.Unit64ToBytes(prog.KeyIndex)) | |
724 | + m.store.SetContractIndex(acct.ID, prog.KeyIndex) | |
715 | 725 | case signers.BIP0044: |
716 | - storeBatch.Set(database.Bip44ContractIndexKey(acct.ID, prog.Change), common.Unit64ToBytes(prog.KeyIndex)) | |
726 | + m.store.SetBip44ContractIndex(acct.ID, prog.Change, prog.KeyIndex) | |
717 | 727 | } |
718 | 728 | } |
719 | - storeBatch.Write() | |
720 | 729 | |
721 | 730 | return nil |
722 | 731 | } |
@@ -31,7 +31,7 @@ func TestReserveBtmUtxoChain(t *testing.T) { | ||
31 | 31 | t.Fatal(err) |
32 | 32 | } |
33 | 33 | |
34 | - m.db.Set(StandardUTXOKey(utxo.OutputID), data) | |
34 | + m.store.SetStandardUTXO(utxo.OutputID, data) | |
35 | 35 | } |
36 | 36 | |
37 | 37 | cases := []struct { |
@@ -5,7 +5,6 @@ import ( | ||
5 | 5 | "encoding/json" |
6 | 6 | |
7 | 7 | log "github.com/sirupsen/logrus" |
8 | - "github.com/vapor/database" | |
9 | 8 | ) |
10 | 9 | |
11 | 10 | // ImageSlice record info of single account |
@@ -29,17 +28,16 @@ func (m *Manager) Backup() (*Image, error) { | ||
29 | 28 | } |
30 | 29 | |
31 | 30 | // GetAccounts() |
32 | - accountIter := m.db.IteratorPrefix([]byte(database.AccountPrefix)) | |
33 | - defer accountIter.Release() | |
34 | - for accountIter.Next() { | |
35 | - a := &Account{} | |
36 | - if err := json.Unmarshal(accountIter.Value(), a); err != nil { | |
31 | + rawAccounts := m.store.GetAccounts("") | |
32 | + | |
33 | + for _, rawAccount := range rawAccounts { | |
34 | + account := new(Account) | |
35 | + if err := json.Unmarshal(rawAccount, account); err != nil { | |
37 | 36 | return nil, err |
38 | 37 | } |
39 | - | |
40 | 38 | image.Slice = append(image.Slice, &ImageSlice{ |
41 | - Account: a, | |
42 | - ContractIndex: m.GetContractIndex(a.ID), | |
39 | + Account: account, | |
40 | + ContractIndex: m.GetContractIndex(account.ID), | |
43 | 41 | }) |
44 | 42 | } |
45 | 43 | return image, nil |
@@ -50,9 +48,11 @@ func (m *Manager) Restore(image *Image) error { | ||
50 | 48 | m.accountMu.Lock() |
51 | 49 | defer m.accountMu.Unlock() |
52 | 50 | |
53 | - storeBatch := m.db.NewBatch() | |
51 | + m.store.InitBatch() | |
52 | + defer m.store.CommitBatch() | |
53 | + | |
54 | 54 | for _, slice := range image.Slice { |
55 | - if existed := m.db.Get(database.AccountIDKey(slice.Account.ID)); existed != nil { | |
55 | + if existed := m.store.GetAccountByAccountID(slice.Account.ID); existed != nil { | |
56 | 56 | log.WithFields(log.Fields{ |
57 | 57 | "module": logModule, |
58 | 58 | "alias": slice.Account.Alias, |
@@ -60,7 +60,7 @@ func (m *Manager) Restore(image *Image) error { | ||
60 | 60 | }).Warning("skip restore account due to already existed") |
61 | 61 | continue |
62 | 62 | } |
63 | - if existed := m.db.Get(database.AccountAliasKey(slice.Account.Alias)); existed != nil { | |
63 | + if existed := m.store.GetAccountByAccountAlias(slice.Account.Alias); existed != nil { | |
64 | 64 | return ErrDuplicateAlias |
65 | 65 | } |
66 | 66 |
@@ -69,10 +69,8 @@ func (m *Manager) Restore(image *Image) error { | ||
69 | 69 | return ErrMarshalAccount |
70 | 70 | } |
71 | 71 | |
72 | - storeBatch.Set(database.AccountIDKey(slice.Account.ID), rawAccount) | |
73 | - storeBatch.Set(database.AccountAliasKey(slice.Account.Alias), []byte(slice.Account.ID)) | |
72 | + m.store.SetAccount(slice.Account.ID, slice.Account.Alias, rawAccount) | |
74 | 73 | } |
75 | 74 | |
76 | - storeBatch.Write() | |
77 | 75 | return nil |
78 | 76 | } |
@@ -2,28 +2,8 @@ package account | ||
2 | 2 | |
3 | 3 | import ( |
4 | 4 | "github.com/vapor/blockchain/query" |
5 | - "github.com/vapor/protocol/bc" | |
6 | 5 | ) |
7 | 6 | |
8 | -const ( | |
9 | - //UTXOPreFix is StandardUTXOKey prefix | |
10 | - UTXOPreFix = "ACU:" | |
11 | - //SUTXOPrefix is ContractUTXOKey prefix | |
12 | - SUTXOPrefix = "SCU:" | |
13 | -) | |
14 | - | |
15 | -// StandardUTXOKey makes an account unspent outputs key to store | |
16 | -func StandardUTXOKey(id bc.Hash) []byte { | |
17 | - name := id.String() | |
18 | - return []byte(UTXOPreFix + name) | |
19 | -} | |
20 | - | |
21 | -// ContractUTXOKey makes a smart contract unspent outputs key to store | |
22 | -func ContractUTXOKey(id bc.Hash) []byte { | |
23 | - name := id.String() | |
24 | - return []byte(SUTXOPrefix + name) | |
25 | -} | |
26 | - | |
27 | 7 | //Annotated init an annotated account object |
28 | 8 | func Annotated(a *Account) *query.AnnotatedAccount { |
29 | 9 | return &query.AnnotatedAccount{ |
@@ -11,7 +11,7 @@ import ( | ||
11 | 11 | |
12 | 12 | log "github.com/sirupsen/logrus" |
13 | 13 | |
14 | - dbm "github.com/vapor/database/leveldb" | |
14 | + "github.com/vapor/database" | |
15 | 15 | "github.com/vapor/errors" |
16 | 16 | "github.com/vapor/protocol/bc" |
17 | 17 | ) |
@@ -56,7 +56,7 @@ type utxoKeeper struct { | ||
56 | 56 | // `sync/atomic` expects the first word in an allocated struct to be 64-bit |
57 | 57 | // aligned on both ARM and x86-32. See https://goo.gl/zW7dgq for more details. |
58 | 58 | nextIndex uint64 |
59 | - db dbm.DB | |
59 | + store database.AccountStorer | |
60 | 60 | mtx sync.RWMutex |
61 | 61 | currentHeight func() uint64 |
62 | 62 |
@@ -65,9 +65,9 @@ type utxoKeeper struct { | ||
65 | 65 | reservations map[uint64]*reservation |
66 | 66 | } |
67 | 67 | |
68 | -func newUtxoKeeper(f func() uint64, walletdb dbm.DB) *utxoKeeper { | |
68 | +func newUtxoKeeper(f func() uint64, store database.AccountStorer) *utxoKeeper { | |
69 | 69 | uk := &utxoKeeper{ |
70 | - db: walletdb, | |
70 | + store: store, | |
71 | 71 | currentHeight: f, |
72 | 72 | unconfirmed: make(map[bc.Hash]*UTXO), |
73 | 73 | reserved: make(map[bc.Hash]uint64), |
@@ -223,16 +223,16 @@ func (uk *utxoKeeper) findUtxos(accountID string, assetID *bc.AssetID, useUnconf | ||
223 | 223 | } |
224 | 224 | } |
225 | 225 | |
226 | - utxoIter := uk.db.IteratorPrefix([]byte(UTXOPreFix)) | |
227 | - defer utxoIter.Release() | |
228 | - for utxoIter.Next() { | |
229 | - u := &UTXO{} | |
230 | - if err := json.Unmarshal(utxoIter.Value(), u); err != nil { | |
226 | + rawUTXOs := uk.store.GetUTXOs() | |
227 | + for _, rawUTXO := range rawUTXOs { | |
228 | + utxo := new(UTXO) | |
229 | + if err := json.Unmarshal(rawUTXO, utxo); err != nil { | |
231 | 230 | log.WithFields(log.Fields{"module": logModule, "err": err}).Error("utxoKeeper findUtxos fail on unmarshal utxo") |
232 | 231 | continue |
233 | 232 | } |
234 | - appendUtxo(u) | |
233 | + appendUtxo(utxo) | |
235 | 234 | } |
235 | + | |
236 | 236 | if !useUnconfirmed { |
237 | 237 | return utxos, immatureAmount |
238 | 238 | } |
@@ -249,10 +249,10 @@ func (uk *utxoKeeper) findUtxo(outHash bc.Hash, useUnconfirmed bool) (*UTXO, err | ||
249 | 249 | } |
250 | 250 | |
251 | 251 | u := &UTXO{} |
252 | - if data := uk.db.Get(StandardUTXOKey(outHash)); data != nil { | |
252 | + if data := uk.store.GetStandardUTXO(outHash); data != nil { | |
253 | 253 | return u, json.Unmarshal(data, u) |
254 | 254 | } |
255 | - if data := uk.db.Get(ContractUTXOKey(outHash)); data != nil { | |
255 | + if data := uk.store.GetContractUTXO(outHash); data != nil { | |
256 | 256 | return u, json.Unmarshal(data, u) |
257 | 257 | } |
258 | 258 | return nil, ErrMatchUTXO |
@@ -6,6 +6,8 @@ import ( | ||
6 | 6 | "testing" |
7 | 7 | "time" |
8 | 8 | |
9 | + "github.com/vapor/database" | |
10 | + | |
9 | 11 | dbm "github.com/vapor/database/leveldb" |
10 | 12 | "github.com/vapor/protocol/bc" |
11 | 13 | "github.com/vapor/testutil" |
@@ -288,13 +290,13 @@ func TestReserve(t *testing.T) { | ||
288 | 290 | }{ |
289 | 291 | { |
290 | 292 | before: utxoKeeper{ |
291 | - db: testDB, | |
293 | + store: database.NewAccountStore(testDB), | |
292 | 294 | currentHeight: currentHeight, |
293 | 295 | reserved: map[bc.Hash]uint64{}, |
294 | 296 | reservations: map[uint64]*reservation{}, |
295 | 297 | }, |
296 | 298 | after: utxoKeeper{ |
297 | - db: testDB, | |
299 | + store: database.NewAccountStore(testDB), | |
298 | 300 | currentHeight: currentHeight, |
299 | 301 | reserved: map[bc.Hash]uint64{}, |
300 | 302 | reservations: map[uint64]*reservation{}, |
@@ -304,7 +306,7 @@ func TestReserve(t *testing.T) { | ||
304 | 306 | }, |
305 | 307 | { |
306 | 308 | before: utxoKeeper{ |
307 | - db: testDB, | |
309 | + store: database.NewAccountStore(testDB), | |
308 | 310 | currentHeight: currentHeight, |
309 | 311 | unconfirmed: map[bc.Hash]*UTXO{ |
310 | 312 | bc.NewHash([32]byte{0x01}): &UTXO{ |
@@ -317,7 +319,7 @@ func TestReserve(t *testing.T) { | ||
317 | 319 | reservations: map[uint64]*reservation{}, |
318 | 320 | }, |
319 | 321 | after: utxoKeeper{ |
320 | - db: testDB, | |
322 | + store: database.NewAccountStore(testDB), | |
321 | 323 | currentHeight: currentHeight, |
322 | 324 | unconfirmed: map[bc.Hash]*UTXO{ |
323 | 325 | bc.NewHash([32]byte{0x01}): &UTXO{ |
@@ -334,7 +336,7 @@ func TestReserve(t *testing.T) { | ||
334 | 336 | }, |
335 | 337 | { |
336 | 338 | before: utxoKeeper{ |
337 | - db: testDB, | |
339 | + store: database.NewAccountStore(testDB), | |
338 | 340 | currentHeight: currentHeight, |
339 | 341 | unconfirmed: map[bc.Hash]*UTXO{ |
340 | 342 | bc.NewHash([32]byte{0x01}): &UTXO{ |
@@ -348,7 +350,7 @@ func TestReserve(t *testing.T) { | ||
348 | 350 | reservations: map[uint64]*reservation{}, |
349 | 351 | }, |
350 | 352 | after: utxoKeeper{ |
351 | - db: testDB, | |
353 | + store: database.NewAccountStore(testDB), | |
352 | 354 | currentHeight: currentHeight, |
353 | 355 | unconfirmed: map[bc.Hash]*UTXO{ |
354 | 356 | bc.NewHash([32]byte{0x01}): &UTXO{ |
@@ -366,7 +368,7 @@ func TestReserve(t *testing.T) { | ||
366 | 368 | }, |
367 | 369 | { |
368 | 370 | before: utxoKeeper{ |
369 | - db: testDB, | |
371 | + store: database.NewAccountStore(testDB), | |
370 | 372 | currentHeight: currentHeight, |
371 | 373 | unconfirmed: map[bc.Hash]*UTXO{ |
372 | 374 | bc.NewHash([32]byte{0x01}): &UTXO{ |
@@ -381,7 +383,7 @@ func TestReserve(t *testing.T) { | ||
381 | 383 | reservations: map[uint64]*reservation{}, |
382 | 384 | }, |
383 | 385 | after: utxoKeeper{ |
384 | - db: testDB, | |
386 | + store: database.NewAccountStore(testDB), | |
385 | 387 | currentHeight: currentHeight, |
386 | 388 | unconfirmed: map[bc.Hash]*UTXO{ |
387 | 389 | bc.NewHash([32]byte{0x01}): &UTXO{ |
@@ -400,7 +402,7 @@ func TestReserve(t *testing.T) { | ||
400 | 402 | }, |
401 | 403 | { |
402 | 404 | before: utxoKeeper{ |
403 | - db: testDB, | |
405 | + store: database.NewAccountStore(testDB), | |
404 | 406 | currentHeight: currentHeight, |
405 | 407 | unconfirmed: map[bc.Hash]*UTXO{ |
406 | 408 | bc.NewHash([32]byte{0x01}): &UTXO{ |
@@ -413,7 +415,7 @@ func TestReserve(t *testing.T) { | ||
413 | 415 | reservations: map[uint64]*reservation{}, |
414 | 416 | }, |
415 | 417 | after: utxoKeeper{ |
416 | - db: testDB, | |
418 | + store: database.NewAccountStore(testDB), | |
417 | 419 | currentHeight: currentHeight, |
418 | 420 | unconfirmed: map[bc.Hash]*UTXO{ |
419 | 421 | bc.NewHash([32]byte{0x01}): &UTXO{ |
@@ -446,7 +448,7 @@ func TestReserve(t *testing.T) { | ||
446 | 448 | }, |
447 | 449 | { |
448 | 450 | before: utxoKeeper{ |
449 | - db: testDB, | |
451 | + store: database.NewAccountStore(testDB), | |
450 | 452 | currentHeight: currentHeight, |
451 | 453 | nextIndex: 1, |
452 | 454 | unconfirmed: map[bc.Hash]*UTXO{ |
@@ -472,7 +474,7 @@ func TestReserve(t *testing.T) { | ||
472 | 474 | reservations: map[uint64]*reservation{}, |
473 | 475 | }, |
474 | 476 | after: utxoKeeper{ |
475 | - db: testDB, | |
477 | + store: database.NewAccountStore(testDB), | |
476 | 478 | currentHeight: currentHeight, |
477 | 479 | unconfirmed: map[bc.Hash]*UTXO{ |
478 | 480 | bc.NewHash([32]byte{0x01}): &UTXO{ |
@@ -522,7 +524,7 @@ func TestReserve(t *testing.T) { | ||
522 | 524 | }, |
523 | 525 | { |
524 | 526 | before: utxoKeeper{ |
525 | - db: testDB, | |
527 | + store: database.NewAccountStore(testDB), | |
526 | 528 | currentHeight: currentHeight, |
527 | 529 | unconfirmed: map[bc.Hash]*UTXO{ |
528 | 530 | bc.NewHash([32]byte{0x01}): &UTXO{ |
@@ -536,7 +538,7 @@ func TestReserve(t *testing.T) { | ||
536 | 538 | reservations: map[uint64]*reservation{}, |
537 | 539 | }, |
538 | 540 | after: utxoKeeper{ |
539 | - db: testDB, | |
541 | + store: database.NewAccountStore(testDB), | |
540 | 542 | currentHeight: currentHeight, |
541 | 543 | unconfirmed: map[bc.Hash]*UTXO{ |
542 | 544 | bc.NewHash([32]byte{0x01}): &UTXO{ |
@@ -594,7 +596,7 @@ func TestReserveParticular(t *testing.T) { | ||
594 | 596 | }{ |
595 | 597 | { |
596 | 598 | before: utxoKeeper{ |
597 | - db: testDB, | |
599 | + store: database.NewAccountStore(testDB), | |
598 | 600 | currentHeight: currentHeight, |
599 | 601 | unconfirmed: map[bc.Hash]*UTXO{ |
600 | 602 | bc.NewHash([32]byte{0x01}): &UTXO{ |
@@ -609,7 +611,7 @@ func TestReserveParticular(t *testing.T) { | ||
609 | 611 | reservations: map[uint64]*reservation{}, |
610 | 612 | }, |
611 | 613 | after: utxoKeeper{ |
612 | - db: testDB, | |
614 | + store: database.NewAccountStore(testDB), | |
613 | 615 | currentHeight: currentHeight, |
614 | 616 | unconfirmed: map[bc.Hash]*UTXO{ |
615 | 617 | bc.NewHash([32]byte{0x01}): &UTXO{ |
@@ -628,7 +630,7 @@ func TestReserveParticular(t *testing.T) { | ||
628 | 630 | }, |
629 | 631 | { |
630 | 632 | before: utxoKeeper{ |
631 | - db: testDB, | |
633 | + store: database.NewAccountStore(testDB), | |
632 | 634 | currentHeight: currentHeight, |
633 | 635 | unconfirmed: map[bc.Hash]*UTXO{ |
634 | 636 | bc.NewHash([32]byte{0x01}): &UTXO{ |
@@ -642,7 +644,7 @@ func TestReserveParticular(t *testing.T) { | ||
642 | 644 | reservations: map[uint64]*reservation{}, |
643 | 645 | }, |
644 | 646 | after: utxoKeeper{ |
645 | - db: testDB, | |
647 | + store: database.NewAccountStore(testDB), | |
646 | 648 | currentHeight: currentHeight, |
647 | 649 | unconfirmed: map[bc.Hash]*UTXO{ |
648 | 650 | bc.NewHash([32]byte{0x01}): &UTXO{ |
@@ -660,7 +662,7 @@ func TestReserveParticular(t *testing.T) { | ||
660 | 662 | }, |
661 | 663 | { |
662 | 664 | before: utxoKeeper{ |
663 | - db: testDB, | |
665 | + store: database.NewAccountStore(testDB), | |
664 | 666 | currentHeight: currentHeight, |
665 | 667 | unconfirmed: map[bc.Hash]*UTXO{ |
666 | 668 | bc.NewHash([32]byte{0x01}): &UTXO{ |
@@ -673,7 +675,7 @@ func TestReserveParticular(t *testing.T) { | ||
673 | 675 | reservations: map[uint64]*reservation{}, |
674 | 676 | }, |
675 | 677 | after: utxoKeeper{ |
676 | - db: testDB, | |
678 | + store: database.NewAccountStore(testDB), | |
677 | 679 | currentHeight: currentHeight, |
678 | 680 | unconfirmed: map[bc.Hash]*UTXO{ |
679 | 681 | bc.NewHash([32]byte{0x01}): &UTXO{ |
@@ -753,7 +755,7 @@ func TestFindUtxos(t *testing.T) { | ||
753 | 755 | }{ |
754 | 756 | { |
755 | 757 | uk: utxoKeeper{ |
756 | - db: testDB, | |
758 | + store: database.NewAccountStore(testDB), | |
757 | 759 | currentHeight: currentHeight, |
758 | 760 | unconfirmed: map[bc.Hash]*UTXO{}, |
759 | 761 | }, |
@@ -764,7 +766,7 @@ func TestFindUtxos(t *testing.T) { | ||
764 | 766 | }, |
765 | 767 | { |
766 | 768 | uk: utxoKeeper{ |
767 | - db: testDB, | |
769 | + store: database.NewAccountStore(testDB), | |
768 | 770 | currentHeight: currentHeight, |
769 | 771 | unconfirmed: map[bc.Hash]*UTXO{}, |
770 | 772 | }, |
@@ -793,7 +795,7 @@ func TestFindUtxos(t *testing.T) { | ||
793 | 795 | }, |
794 | 796 | { |
795 | 797 | uk: utxoKeeper{ |
796 | - db: testDB, | |
798 | + store: database.NewAccountStore(testDB), | |
797 | 799 | currentHeight: currentHeight, |
798 | 800 | unconfirmed: map[bc.Hash]*UTXO{}, |
799 | 801 | }, |
@@ -811,7 +813,7 @@ func TestFindUtxos(t *testing.T) { | ||
811 | 813 | }, |
812 | 814 | { |
813 | 815 | uk: utxoKeeper{ |
814 | - db: testDB, | |
816 | + store: database.NewAccountStore(testDB), | |
815 | 817 | currentHeight: currentHeight, |
816 | 818 | unconfirmed: map[bc.Hash]*UTXO{ |
817 | 819 | bc.NewHash([32]byte{0x01}): &UTXO{ |
@@ -840,7 +842,7 @@ func TestFindUtxos(t *testing.T) { | ||
840 | 842 | }, |
841 | 843 | { |
842 | 844 | uk: utxoKeeper{ |
843 | - db: testDB, | |
845 | + store: database.NewAccountStore(testDB), | |
844 | 846 | currentHeight: currentHeight, |
845 | 847 | unconfirmed: map[bc.Hash]*UTXO{ |
846 | 848 | bc.NewHash([32]byte{0x11}): &UTXO{ |
@@ -874,7 +876,7 @@ func TestFindUtxos(t *testing.T) { | ||
874 | 876 | }, |
875 | 877 | { |
876 | 878 | uk: utxoKeeper{ |
877 | - db: testDB, | |
879 | + store: database.NewAccountStore(testDB), | |
878 | 880 | currentHeight: currentHeight, |
879 | 881 | unconfirmed: map[bc.Hash]*UTXO{ |
880 | 882 | bc.NewHash([32]byte{0x01}): &UTXO{ |
@@ -918,7 +920,7 @@ func TestFindUtxos(t *testing.T) { | ||
918 | 920 | }, |
919 | 921 | { |
920 | 922 | uk: utxoKeeper{ |
921 | - db: testDB, | |
923 | + store: database.NewAccountStore(testDB), | |
922 | 924 | currentHeight: currentHeight, |
923 | 925 | unconfirmed: map[bc.Hash]*UTXO{}, |
924 | 926 | }, |
@@ -950,7 +952,7 @@ func TestFindUtxos(t *testing.T) { | ||
950 | 952 | if err != nil { |
951 | 953 | t.Error(err) |
952 | 954 | } |
953 | - testDB.Set(StandardUTXOKey(u.OutputID), data) | |
955 | + testDB.Set(database.StandardUTXOKey(u.OutputID), data) | |
954 | 956 | } |
955 | 957 | |
956 | 958 | gotUtxos, immatureAmount := c.uk.findUtxos("testAccount", &bc.AssetID{}, c.useUnconfirmed, c.vote) |
@@ -962,7 +964,7 @@ func TestFindUtxos(t *testing.T) { | ||
962 | 964 | } |
963 | 965 | |
964 | 966 | for _, u := range c.dbUtxos { |
965 | - testDB.Delete(StandardUTXOKey(u.OutputID)) | |
967 | + testDB.Delete(database.StandardUTXOKey(u.OutputID)) | |
966 | 968 | } |
967 | 969 | } |
968 | 970 | } |
@@ -982,7 +984,7 @@ func TestFindUtxo(t *testing.T) { | ||
982 | 984 | }{ |
983 | 985 | { |
984 | 986 | uk: utxoKeeper{ |
985 | - db: testDB, | |
987 | + store: database.NewAccountStore(testDB), | |
986 | 988 | currentHeight: currentHeight, |
987 | 989 | unconfirmed: map[bc.Hash]*UTXO{}, |
988 | 990 | }, |
@@ -993,7 +995,7 @@ func TestFindUtxo(t *testing.T) { | ||
993 | 995 | }, |
994 | 996 | { |
995 | 997 | uk: utxoKeeper{ |
996 | - db: testDB, | |
998 | + store: database.NewAccountStore(testDB), | |
997 | 999 | currentHeight: currentHeight, |
998 | 1000 | unconfirmed: map[bc.Hash]*UTXO{ |
999 | 1001 | bc.NewHash([32]byte{0x01}): &UTXO{OutputID: bc.NewHash([32]byte{0x01})}, |
@@ -1007,7 +1009,7 @@ func TestFindUtxo(t *testing.T) { | ||
1007 | 1009 | }, |
1008 | 1010 | { |
1009 | 1011 | uk: utxoKeeper{ |
1010 | - db: testDB, | |
1012 | + store: database.NewAccountStore(testDB), | |
1011 | 1013 | currentHeight: currentHeight, |
1012 | 1014 | unconfirmed: map[bc.Hash]*UTXO{ |
1013 | 1015 | bc.NewHash([32]byte{0x01}): &UTXO{OutputID: bc.NewHash([32]byte{0x01})}, |
@@ -1021,12 +1023,12 @@ func TestFindUtxo(t *testing.T) { | ||
1021 | 1023 | }, |
1022 | 1024 | { |
1023 | 1025 | uk: utxoKeeper{ |
1024 | - db: testDB, | |
1026 | + store: database.NewAccountStore(testDB), | |
1025 | 1027 | currentHeight: currentHeight, |
1026 | 1028 | unconfirmed: map[bc.Hash]*UTXO{}, |
1027 | 1029 | }, |
1028 | 1030 | dbUtxos: map[string]*UTXO{ |
1029 | - string(StandardUTXOKey(bc.NewHash([32]byte{0x01}))): &UTXO{OutputID: bc.NewHash([32]byte{0x01})}, | |
1031 | + string(database.StandardUTXOKey(bc.NewHash([32]byte{0x01}))): &UTXO{OutputID: bc.NewHash([32]byte{0x01})}, | |
1030 | 1032 | }, |
1031 | 1033 | outHash: bc.NewHash([32]byte{0x01}), |
1032 | 1034 | wantUtxo: &UTXO{OutputID: bc.NewHash([32]byte{0x01})}, |
@@ -1035,12 +1037,12 @@ func TestFindUtxo(t *testing.T) { | ||
1035 | 1037 | }, |
1036 | 1038 | { |
1037 | 1039 | uk: utxoKeeper{ |
1038 | - db: testDB, | |
1040 | + store: database.NewAccountStore(testDB), | |
1039 | 1041 | currentHeight: currentHeight, |
1040 | 1042 | unconfirmed: map[bc.Hash]*UTXO{}, |
1041 | 1043 | }, |
1042 | 1044 | dbUtxos: map[string]*UTXO{ |
1043 | - string(ContractUTXOKey(bc.NewHash([32]byte{0x01}))): &UTXO{OutputID: bc.NewHash([32]byte{0x01})}, | |
1045 | + string(database.ContractUTXOKey(bc.NewHash([32]byte{0x01}))): &UTXO{OutputID: bc.NewHash([32]byte{0x01})}, | |
1044 | 1046 | }, |
1045 | 1047 | outHash: bc.NewHash([32]byte{0x01}), |
1046 | 1048 | wantUtxo: &UTXO{OutputID: bc.NewHash([32]byte{0x01})}, |
@@ -1067,7 +1069,7 @@ func TestFindUtxo(t *testing.T) { | ||
1067 | 1069 | } |
1068 | 1070 | |
1069 | 1071 | for _, u := range c.dbUtxos { |
1070 | - testDB.Delete(StandardUTXOKey(u.OutputID)) | |
1072 | + testDB.Delete(database.StandardUTXOKey(u.OutputID)) | |
1071 | 1073 | } |
1072 | 1074 | } |
1073 | 1075 | } |
@@ -11,10 +11,12 @@ import ( | ||
11 | 11 | |
12 | 12 | // AccountStorer interface contains account storage functions. |
13 | 13 | type AccountStorer interface { |
14 | + InitBatch() | |
15 | + CommitBatch() | |
14 | 16 | SetAccount(string, string, []byte) |
15 | 17 | SetAccountIndex([]chainkd.XPub, uint64) |
16 | 18 | GetAccountByAccountAlias(string) []byte |
17 | - GetAccountByAccountID(string) []byte // duplicate in WalletStorer | |
19 | + GetAccountByAccountID(string) []byte | |
18 | 20 | GetAccountIndex([]chainkd.XPub) []byte |
19 | 21 | DeleteAccountByAccountAlias(string) |
20 | 22 | DeleteAccountByAccountID(string) |
@@ -23,21 +25,24 @@ type AccountStorer interface { | ||
23 | 25 | DeleteContractIndex(string) |
24 | 26 | GetContractIndex(string) []byte |
25 | 27 | // DeleteAccountUTXOs(string) error |
28 | + GetAccountUTXOs(string) [][]byte | |
29 | + DeleteUTXO(bc.Hash) | |
26 | 30 | GetCoinbaseArbitrary() []byte |
27 | 31 | SetCoinbaseArbitrary([]byte) |
28 | 32 | GetMiningAddress() []byte |
29 | 33 | GetFirstAccount() ([]byte, error) |
30 | 34 | SetMiningAddress([]byte) |
31 | 35 | GetBip44ContractIndex(string, bool) []byte |
32 | - GetRawProgram(common.Hash) []byte // duplicate in WalletStorer | |
33 | - GetAccounts(string) ([][]byte, error) | |
36 | + GetRawProgram(common.Hash) []byte | |
37 | + GetAccounts(string) [][]byte | |
34 | 38 | GetControlPrograms() ([][]byte, error) |
35 | 39 | SetRawProgram(common.Hash, []byte) |
36 | 40 | SetContractIndex(string, uint64) |
37 | 41 | SetBip44ContractIndex(string, bool, uint64) |
38 | - GetUTXOs(string) [][]byte | |
39 | - GetStandardUTXO(bc.Hash) []byte // duplicate in WalletStorer | |
42 | + GetUTXOs() [][]byte | |
43 | + GetStandardUTXO(bc.Hash) []byte | |
40 | 44 | GetContractUTXO(bc.Hash) []byte |
45 | + SetStandardUTXO(bc.Hash, []byte) | |
41 | 46 | } |
42 | 47 | |
43 | 48 | // AccountStore satisfies AccountStorer interface. |
@@ -54,17 +59,54 @@ func NewAccountStore(db dbm.DB) *AccountStore { | ||
54 | 59 | } |
55 | 60 | } |
56 | 61 | |
62 | +// InitBatch initial batch | |
63 | +func (store *AccountStore) InitBatch() { | |
64 | + if store.batch == nil { | |
65 | + store.batch = store.accountDB.NewBatch() | |
66 | + } | |
67 | +} | |
68 | + | |
69 | +// CommitBatch commit batch | |
70 | +func (store *AccountStore) CommitBatch() { | |
71 | + if store.batch != nil { | |
72 | + store.batch.Write() | |
73 | + store.batch = nil | |
74 | + } | |
75 | +} | |
76 | + | |
57 | 77 | // SetAccount set account account ID, account alias and raw account. |
58 | 78 | func (store *AccountStore) SetAccount(accountID, accountAlias string, rawAccount []byte) { |
59 | 79 | batch := store.accountDB.NewBatch() |
80 | + if store.batch != nil { | |
81 | + batch = store.batch | |
82 | + } | |
60 | 83 | batch.Set(AccountIDKey(accountID), rawAccount) |
61 | 84 | batch.Set(AccountAliasKey(accountAlias), []byte(accountID)) |
62 | - batch.Write() | |
85 | + if store.batch == nil { | |
86 | + batch.Write() | |
87 | + } | |
88 | +} | |
89 | + | |
90 | +// DeleteAccount set account account ID, account alias and raw account. | |
91 | +func (store *AccountStore) DeleteAccount(accountID, accountAlias string) { | |
92 | + batch := store.accountDB.NewBatch() | |
93 | + if store.batch != nil { | |
94 | + batch = store.batch | |
95 | + } | |
96 | + batch.Delete(AccountIDKey(accountID)) | |
97 | + batch.Delete(AccountAliasKey(accountAlias)) | |
98 | + if store.batch == nil { | |
99 | + batch.Write() | |
100 | + } | |
63 | 101 | } |
64 | 102 | |
65 | 103 | // SetAccountIndex set account index |
66 | 104 | func (store *AccountStore) SetAccountIndex(xpubs []chainkd.XPub, keyIndex uint64) { |
67 | - store.accountDB.Set(AccountIndexKey(xpubs), common.Unit64ToBytes(keyIndex)) | |
105 | + if store.batch == nil { | |
106 | + store.accountDB.Set(AccountIndexKey(xpubs), common.Unit64ToBytes(keyIndex)) | |
107 | + } else { | |
108 | + store.batch.Set(AccountIndexKey(xpubs), common.Unit64ToBytes(keyIndex)) | |
109 | + } | |
68 | 110 | } |
69 | 111 | |
70 | 112 | // GetAccountByAccountAlias get account by account alias |
@@ -84,30 +126,51 @@ func (store *AccountStore) GetAccountIndex(xpubs []chainkd.XPub) []byte { | ||
84 | 126 | |
85 | 127 | // DeleteAccountByAccountAlias delete account by account alias |
86 | 128 | func (store *AccountStore) DeleteAccountByAccountAlias(accountAlias string) { |
87 | - store.accountDB.Delete(AccountAliasKey(accountAlias)) | |
129 | + if store.batch == nil { | |
130 | + store.accountDB.Delete(AccountAliasKey(accountAlias)) | |
131 | + } else { | |
132 | + store.batch.Delete(AccountAliasKey(accountAlias)) | |
133 | + } | |
88 | 134 | } |
89 | 135 | |
90 | 136 | // DeleteAccountByAccountID delete account by accountID |
91 | 137 | func (store *AccountStore) DeleteAccountByAccountID(accountID string) { |
92 | - store.accountDB.Delete(AccountIDKey(accountID)) | |
138 | + if store.batch == nil { | |
139 | + store.accountDB.Delete(AccountIDKey(accountID)) | |
140 | + } else { | |
141 | + store.batch.Delete(AccountIDKey(accountID)) | |
142 | + } | |
93 | 143 | } |
94 | 144 | |
95 | 145 | // DeleteRawProgram delete raw control program by hash |
96 | 146 | func (store *AccountStore) DeleteRawProgram(hash common.Hash) { |
97 | - store.accountDB.Delete(ContractKey(hash)) | |
147 | + if store.batch == nil { | |
148 | + store.accountDB.Delete(ContractKey(hash)) | |
149 | + } else { | |
150 | + store.batch.Delete(ContractKey(hash)) | |
151 | + } | |
98 | 152 | } |
99 | 153 | |
100 | 154 | // DeleteBip44ContractIndex delete bip44 contract index by accountID |
101 | 155 | func (store *AccountStore) DeleteBip44ContractIndex(accountID string) { |
102 | 156 | batch := store.accountDB.NewBatch() |
157 | + if store.batch != nil { | |
158 | + batch = store.batch | |
159 | + } | |
103 | 160 | batch.Delete(Bip44ContractIndexKey(accountID, false)) |
104 | 161 | batch.Delete(Bip44ContractIndexKey(accountID, true)) |
105 | - batch.Write() | |
162 | + if store.batch == nil { | |
163 | + batch.Write() | |
164 | + } | |
106 | 165 | } |
107 | 166 | |
108 | 167 | // DeleteContractIndex delete contract index by accountID |
109 | 168 | func (store *AccountStore) DeleteContractIndex(accountID string) { |
110 | - store.accountDB.Delete(ContractIndexKey(accountID)) | |
169 | + if store.batch == nil { | |
170 | + store.accountDB.Delete(ContractIndexKey(accountID)) | |
171 | + } else { | |
172 | + store.batch.Delete(ContractIndexKey(accountID)) | |
173 | + } | |
111 | 174 | } |
112 | 175 | |
113 | 176 | // GetContractIndex get contract index |
@@ -115,22 +178,26 @@ func (store *AccountStore) GetContractIndex(accountID string) []byte { | ||
115 | 178 | return store.accountDB.Get(ContractIndexKey(accountID)) |
116 | 179 | } |
117 | 180 | |
118 | -// // DeleteAccountUTXOs delete account utxos by accountID | |
119 | -// func (store *AccountStore) DeleteAccountUTXOs(accountID string) error { | |
120 | -// accountUtxoIter := store.accountDB.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 | -// } | |
181 | +// GetAccountUTXOs get account utxos by account id | |
182 | +func (store *AccountStore) GetAccountUTXOs(accountID string) [][]byte { | |
183 | + accountUtxoIter := store.accountDB.IteratorPrefix([]byte(UTXOPrefix)) | |
184 | + defer accountUtxoIter.Release() | |
185 | + | |
186 | + utxos := make([][]byte, 0) | |
187 | + for accountUtxoIter.Next() { | |
188 | + utxos = append(utxos, accountUtxoIter.Value()) | |
189 | + } | |
190 | + return utxos | |
191 | +} | |
127 | 192 | |
128 | -// if accountID == accountUtxo.AccountID { | |
129 | -// store.accountDB.Delete(StandardUTXOKey(accountUtxo.OutputID)) | |
130 | -// } | |
131 | -// } | |
132 | -// return nil | |
133 | -// } | |
193 | +// DeleteUTXO delete utxo by outpu id | |
194 | +func (store *AccountStore) DeleteUTXO(outputID bc.Hash) { | |
195 | + if store.batch == nil { | |
196 | + store.accountDB.Delete(StandardUTXOKey(outputID)) | |
197 | + } else { | |
198 | + store.batch.Delete(StandardUTXOKey(outputID)) | |
199 | + } | |
200 | +} | |
134 | 201 | |
135 | 202 | // GetCoinbaseArbitrary get coinbase arbitrary |
136 | 203 | func (store *AccountStore) GetCoinbaseArbitrary() []byte { |
@@ -139,7 +206,11 @@ func (store *AccountStore) GetCoinbaseArbitrary() []byte { | ||
139 | 206 | |
140 | 207 | // SetCoinbaseArbitrary set coinbase arbitrary |
141 | 208 | func (store *AccountStore) SetCoinbaseArbitrary(arbitrary []byte) { |
142 | - store.accountDB.Set([]byte(CoinbaseAbKey), arbitrary) | |
209 | + if store.batch == nil { | |
210 | + store.accountDB.Set([]byte(CoinbaseAbKey), arbitrary) | |
211 | + } else { | |
212 | + store.batch.Set([]byte(CoinbaseAbKey), arbitrary) | |
213 | + } | |
143 | 214 | } |
144 | 215 | |
145 | 216 | // GetMiningAddress get mining address |
@@ -151,6 +222,7 @@ func (store *AccountStore) GetMiningAddress() []byte { | ||
151 | 222 | func (store *AccountStore) GetFirstAccount() ([]byte, error) { |
152 | 223 | accountIter := store.accountDB.IteratorPrefix([]byte(AccountPrefix)) |
153 | 224 | defer accountIter.Release() |
225 | + | |
154 | 226 | if !accountIter.Next() { |
155 | 227 | return nil, ErrFindAccount |
156 | 228 | } |
@@ -159,7 +231,11 @@ func (store *AccountStore) GetFirstAccount() ([]byte, error) { | ||
159 | 231 | |
160 | 232 | // SetMiningAddress set mining address |
161 | 233 | func (store *AccountStore) SetMiningAddress(rawProgram []byte) { |
162 | - store.accountDB.Set([]byte(MiningAddressKey), rawProgram) | |
234 | + if store.batch == nil { | |
235 | + store.accountDB.Set([]byte(MiningAddressKey), rawProgram) | |
236 | + } else { | |
237 | + store.batch.Set([]byte(MiningAddressKey), rawProgram) | |
238 | + } | |
163 | 239 | } |
164 | 240 | |
165 | 241 | // GetBip44ContractIndex get bip44 contract index |
@@ -173,23 +249,23 @@ func (store *AccountStore) GetRawProgram(hash common.Hash) []byte { | ||
173 | 249 | } |
174 | 250 | |
175 | 251 | // GetAccounts get all accounts which name prfix is id. |
176 | -func (store *AccountStore) GetAccounts(id string) ([][]byte, error) { | |
177 | - accounts := make([][]byte, 0) | |
252 | +func (store *AccountStore) GetAccounts(id string) [][]byte { | |
178 | 253 | accountIter := store.accountDB.IteratorPrefix(AccountIDKey(strings.TrimSpace(id))) |
179 | 254 | defer accountIter.Release() |
180 | 255 | |
256 | + accounts := make([][]byte, 0) | |
181 | 257 | for accountIter.Next() { |
182 | 258 | accounts = append(accounts, accountIter.Value()) |
183 | 259 | } |
184 | - return accounts, nil | |
260 | + return accounts | |
185 | 261 | } |
186 | 262 | |
187 | 263 | // GetControlPrograms get all local control programs |
188 | 264 | func (store *AccountStore) GetControlPrograms() ([][]byte, error) { |
189 | - cps := make([][]byte, 0) | |
190 | 265 | cpIter := store.accountDB.IteratorPrefix([]byte(ContractPrefix)) |
191 | 266 | defer cpIter.Release() |
192 | 267 | |
268 | + cps := make([][]byte, 0) | |
193 | 269 | for cpIter.Next() { |
194 | 270 | cps = append(cps, cpIter.Value()) |
195 | 271 | } |
@@ -198,25 +274,37 @@ func (store *AccountStore) GetControlPrograms() ([][]byte, error) { | ||
198 | 274 | |
199 | 275 | // SetRawProgram set raw program |
200 | 276 | func (store *AccountStore) SetRawProgram(hash common.Hash, program []byte) { |
201 | - store.accountDB.Set(ContractKey(hash), program) | |
277 | + if store.batch == nil { | |
278 | + store.accountDB.Set(ContractKey(hash), program) | |
279 | + } else { | |
280 | + store.batch.Set(ContractKey(hash), program) | |
281 | + } | |
202 | 282 | } |
203 | 283 | |
204 | 284 | // SetContractIndex set contract index |
205 | 285 | func (store *AccountStore) SetContractIndex(accountID string, index uint64) { |
206 | - store.accountDB.Set(ContractIndexKey(accountID), common.Unit64ToBytes(index)) | |
286 | + if store.batch == nil { | |
287 | + store.accountDB.Set(ContractIndexKey(accountID), common.Unit64ToBytes(index)) | |
288 | + } else { | |
289 | + store.batch.Set(ContractIndexKey(accountID), common.Unit64ToBytes(index)) | |
290 | + } | |
207 | 291 | } |
208 | 292 | |
209 | 293 | // SetBip44ContractIndex set contract index |
210 | 294 | func (store *AccountStore) SetBip44ContractIndex(accountID string, change bool, index uint64) { |
211 | - store.accountDB.Set(Bip44ContractIndexKey(accountID, change), common.Unit64ToBytes(index)) | |
295 | + if store.batch == nil { | |
296 | + store.accountDB.Set(Bip44ContractIndexKey(accountID, change), common.Unit64ToBytes(index)) | |
297 | + } else { | |
298 | + store.batch.Set(Bip44ContractIndexKey(accountID, change), common.Unit64ToBytes(index)) | |
299 | + } | |
212 | 300 | } |
213 | 301 | |
214 | 302 | // GetUTXOs get utxos by accountID |
215 | -func (store *AccountStore) GetUTXOs(accountID string) [][]byte { | |
216 | - utxos := make([][]byte, 0) | |
303 | +func (store *AccountStore) GetUTXOs() [][]byte { | |
217 | 304 | utxoIter := store.accountDB.IteratorPrefix([]byte(UTXOPrefix)) |
218 | 305 | defer utxoIter.Release() |
219 | 306 | |
307 | + utxos := make([][]byte, 0) | |
220 | 308 | for utxoIter.Next() { |
221 | 309 | utxos = append(utxos, utxoIter.Value()) |
222 | 310 | } |
@@ -232,3 +320,12 @@ func (store *AccountStore) GetStandardUTXO(outid bc.Hash) []byte { | ||
232 | 320 | func (store *AccountStore) GetContractUTXO(outid bc.Hash) []byte { |
233 | 321 | return store.accountDB.Get(ContractUTXOKey(outid)) |
234 | 322 | } |
323 | + | |
324 | +// SetStandardUTXO set standard utxo | |
325 | +func (store *AccountStore) SetStandardUTXO(outputID bc.Hash, data []byte) { | |
326 | + if store.batch == nil { | |
327 | + store.accountDB.Set(StandardUTXOKey(outputID), data) | |
328 | + } else { | |
329 | + store.batch.Set(StandardUTXOKey(outputID), data) | |
330 | + } | |
331 | +} |
@@ -9,6 +9,7 @@ import ( | ||
9 | 9 | "github.com/vapor/consensus" |
10 | 10 | "github.com/vapor/consensus/segwit" |
11 | 11 | "github.com/vapor/crypto/sha3pool" |
12 | + "github.com/vapor/database" | |
12 | 13 | "github.com/vapor/errors" |
13 | 14 | "github.com/vapor/protocol/bc" |
14 | 15 | "github.com/vapor/protocol/bc/types" |
@@ -16,9 +17,9 @@ import ( | ||
16 | 17 | |
17 | 18 | // GetAccountUtxos return all account unspent outputs |
18 | 19 | func (w *Wallet) GetAccountUtxos(accountID string, id string, unconfirmed, isSmartContract bool, vote bool) []*account.UTXO { |
19 | - prefix := account.UTXOPreFix | |
20 | + prefix := database.UTXOPrefix | |
20 | 21 | if isSmartContract { |
21 | - prefix = account.SUTXOPrefix | |
22 | + prefix = database.SUTXOPrefix | |
22 | 23 | } |
23 | 24 | |
24 | 25 | accountUtxos := []*account.UTXO{} |
@@ -42,16 +42,16 @@ func TestGetAccountUtxos(t *testing.T) { | ||
42 | 42 | }, |
43 | 43 | { |
44 | 44 | dbUtxos: map[string]*account.UTXO{ |
45 | - string(account.StandardUTXOKey(bc.Hash{V0: 1})): &account.UTXO{ | |
45 | + string(database.StandardUTXOKey(bc.Hash{V0: 1})): &account.UTXO{ | |
46 | 46 | OutputID: bc.Hash{V0: 1}, |
47 | 47 | }, |
48 | - string(account.StandardUTXOKey(bc.Hash{V0: 2})): &account.UTXO{ | |
48 | + string(database.StandardUTXOKey(bc.Hash{V0: 2})): &account.UTXO{ | |
49 | 49 | OutputID: bc.Hash{V0: 2}, |
50 | 50 | }, |
51 | - string(account.StandardUTXOKey(bc.Hash{V0: 3})): &account.UTXO{ | |
51 | + string(database.StandardUTXOKey(bc.Hash{V0: 3})): &account.UTXO{ | |
52 | 52 | OutputID: bc.Hash{V0: 3}, |
53 | 53 | }, |
54 | - string(account.ContractUTXOKey(bc.Hash{V0: 4})): &account.UTXO{ | |
54 | + string(database.ContractUTXOKey(bc.Hash{V0: 4})): &account.UTXO{ | |
55 | 55 | OutputID: bc.Hash{V0: 4}, |
56 | 56 | }, |
57 | 57 | }, |
@@ -66,16 +66,16 @@ func TestGetAccountUtxos(t *testing.T) { | ||
66 | 66 | }, |
67 | 67 | { |
68 | 68 | dbUtxos: map[string]*account.UTXO{ |
69 | - string(account.StandardUTXOKey(bc.Hash{V0: 1})): &account.UTXO{ | |
69 | + string(database.StandardUTXOKey(bc.Hash{V0: 1})): &account.UTXO{ | |
70 | 70 | OutputID: bc.Hash{V0: 1}, |
71 | 71 | }, |
72 | - string(account.StandardUTXOKey(bc.Hash{V0: 2})): &account.UTXO{ | |
72 | + string(database.StandardUTXOKey(bc.Hash{V0: 2})): &account.UTXO{ | |
73 | 73 | OutputID: bc.Hash{V0: 2}, |
74 | 74 | }, |
75 | - string(account.StandardUTXOKey(bc.Hash{V0: 3})): &account.UTXO{ | |
75 | + string(database.StandardUTXOKey(bc.Hash{V0: 3})): &account.UTXO{ | |
76 | 76 | OutputID: bc.Hash{V0: 3}, |
77 | 77 | }, |
78 | - string(account.ContractUTXOKey(bc.Hash{V0: 4})): &account.UTXO{ | |
78 | + string(database.ContractUTXOKey(bc.Hash{V0: 4})): &account.UTXO{ | |
79 | 79 | OutputID: bc.Hash{V0: 4}, |
80 | 80 | }, |
81 | 81 | }, |
@@ -94,16 +94,16 @@ func TestGetAccountUtxos(t *testing.T) { | ||
94 | 94 | }, |
95 | 95 | { |
96 | 96 | dbUtxos: map[string]*account.UTXO{ |
97 | - string(account.StandardUTXOKey(bc.Hash{V0: 1})): &account.UTXO{ | |
97 | + string(database.StandardUTXOKey(bc.Hash{V0: 1})): &account.UTXO{ | |
98 | 98 | OutputID: bc.Hash{V0: 1}, |
99 | 99 | }, |
100 | - string(account.StandardUTXOKey(bc.Hash{V0: 1, V1: 2})): &account.UTXO{ | |
100 | + string(database.StandardUTXOKey(bc.Hash{V0: 1, V1: 2})): &account.UTXO{ | |
101 | 101 | OutputID: bc.Hash{V0: 1, V1: 2}, |
102 | 102 | }, |
103 | - string(account.StandardUTXOKey(bc.Hash{V0: 2})): &account.UTXO{ | |
103 | + string(database.StandardUTXOKey(bc.Hash{V0: 2})): &account.UTXO{ | |
104 | 104 | OutputID: bc.Hash{V0: 2}, |
105 | 105 | }, |
106 | - string(account.StandardUTXOKey(bc.Hash{V0: 2, V1: 2})): &account.UTXO{ | |
106 | + string(database.StandardUTXOKey(bc.Hash{V0: 2, V1: 2})): &account.UTXO{ | |
107 | 107 | OutputID: bc.Hash{V0: 2, V1: 2}, |
108 | 108 | }, |
109 | 109 | }, |
@@ -123,10 +123,10 @@ func TestGetAccountUtxos(t *testing.T) { | ||
123 | 123 | }, |
124 | 124 | { |
125 | 125 | dbUtxos: map[string]*account.UTXO{ |
126 | - string(account.StandardUTXOKey(bc.Hash{V0: 3})): &account.UTXO{ | |
126 | + string(database.StandardUTXOKey(bc.Hash{V0: 3})): &account.UTXO{ | |
127 | 127 | OutputID: bc.Hash{V0: 3}, |
128 | 128 | }, |
129 | - string(account.ContractUTXOKey(bc.Hash{V0: 4})): &account.UTXO{ | |
129 | + string(database.ContractUTXOKey(bc.Hash{V0: 4})): &account.UTXO{ | |
130 | 130 | OutputID: bc.Hash{V0: 4}, |
131 | 131 | }, |
132 | 132 | }, |
@@ -155,10 +155,10 @@ func TestGetAccountUtxos(t *testing.T) { | ||
155 | 155 | }, |
156 | 156 | { |
157 | 157 | dbUtxos: map[string]*account.UTXO{ |
158 | - string(account.StandardUTXOKey(bc.Hash{V0: 3})): &account.UTXO{ | |
158 | + string(database.StandardUTXOKey(bc.Hash{V0: 3})): &account.UTXO{ | |
159 | 159 | OutputID: bc.Hash{V0: 3}, |
160 | 160 | }, |
161 | - string(account.ContractUTXOKey(bc.Hash{V0: 4})): &account.UTXO{ | |
161 | + string(database.ContractUTXOKey(bc.Hash{V0: 4})): &account.UTXO{ | |
162 | 162 | OutputID: bc.Hash{V0: 4}, |
163 | 163 | }, |
164 | 164 | }, |