OSDN Git Service

finish account wallet-store-interface-account
authorChengcheng Zhang <943420582@qq.com>
Tue, 25 Jun 2019 15:19:06 +0000 (23:19 +0800)
committerChengcheng Zhang <943420582@qq.com>
Tue, 25 Jun 2019 15:19:06 +0000 (23:19 +0800)
account/accounts.go
account/builder_test.go
account/image.go
account/indexer.go
account/utxo_keeper.go
account/utxo_keeper_test.go
database/account_store.go
wallet/utxo.go
wallet/utxo_test.go

index da18e57..42c04b2 100644 (file)
@@ -67,7 +67,7 @@ type CtrlProgram struct {
 
 // Manager stores accounts and their associated control programs.
 type Manager struct {
-       db         dbm.DB
+       store      database.AccountStorer
        chain      *protocol.Chain
        utxoKeeper *utxoKeeper
 
@@ -83,11 +83,12 @@ type Manager struct {
 }
 
 // NewManager creates a new account manager
-func NewManager(walletDB dbm.DB, chain *protocol.Chain) *Manager {
+func NewManager(accountdb dbm.DB, chain *protocol.Chain) *Manager {
+       store := database.NewAccountStore(accountdb)
        return &Manager{
-               db:          walletDB,
+               store:       store,
                chain:       chain,
-               utxoKeeper:  newUtxoKeeper(chain.BestBlockHeight, walletDB),
+               utxoKeeper:  newUtxoKeeper(chain.BestBlockHeight, store),
                cache:       lru.New(maxAccountCache),
                aliasCache:  lru.New(maxAccountCache),
                delayedACPs: make(map[*txbuilder.TemplateBuilder][]*CtrlProgram),
@@ -120,13 +121,14 @@ func (m *Manager) saveAccount(account *Account, updateIndex bool) error {
                return ErrMarshalAccount
        }
 
-       storeBatch := m.db.NewBatch()
-       storeBatch.Set(database.AccountIDKey(account.ID), rawAccount)
-       storeBatch.Set(database.AccountAliasKey(account.Alias), []byte(account.ID))
+       m.store.InitBatch()
+       defer m.store.CommitBatch()
+
+       m.store.SetAccount(account.ID, account.Alias, rawAccount)
        if updateIndex {
-               storeBatch.Set(database.AccountIndexKey(account.XPubs), common.Unit64ToBytes(account.KeyIndex))
+               m.store.SetAccountIndex(account.XPubs, account.KeyIndex)
        }
-       storeBatch.Write()
+
        return nil
 }
 
@@ -135,7 +137,7 @@ func (m *Manager) SaveAccount(account *Account) error {
        m.accountMu.Lock()
        defer m.accountMu.Unlock()
 
-       if existed := m.db.Get(database.AccountAliasKey(account.Alias)); existed != nil {
+       if existed := m.store.GetAccountByAccountAlias(account.Alias); existed != nil {
                return ErrDuplicateAlias
        }
 
@@ -149,7 +151,7 @@ func (m *Manager) SaveAccount(account *Account) error {
        }
 
        currentIndex := uint64(0)
-       if rawIndexBytes := m.db.Get(database.AccountIndexKey(account.XPubs)); rawIndexBytes != nil {
+       if rawIndexBytes := m.store.GetAccountIndex(account.XPubs); rawIndexBytes != nil {
                currentIndex = common.BytesToUnit64(rawIndexBytes)
        }
        return m.saveAccount(account, account.KeyIndex > currentIndex)
@@ -160,12 +162,12 @@ func (m *Manager) Create(xpubs []chainkd.XPub, quorum int, alias string, deriveR
        m.accountMu.Lock()
        defer m.accountMu.Unlock()
 
-       if existed := m.db.Get(database.AccountAliasKey(alias)); existed != nil {
+       if existed := m.store.GetAccountByAccountAlias(alias); existed != nil {
                return nil, ErrDuplicateAlias
        }
 
        acctIndex := uint64(1)
-       if rawIndexBytes := m.db.Get(database.AccountIndexKey(xpubs)); rawIndexBytes != nil {
+       if rawIndexBytes := m.store.GetAccountIndex(xpubs); rawIndexBytes != nil {
                acctIndex = common.BytesToUnit64(rawIndexBytes) + 1
        }
        account, err := CreateAccount(xpubs, quorum, alias, acctIndex, deriveRule)
@@ -191,7 +193,7 @@ func (m *Manager) UpdateAccountAlias(accountID string, newAlias string) (err err
        oldAlias := account.Alias
 
        normalizedAlias := strings.ToLower(strings.TrimSpace(newAlias))
-       if existed := m.db.Get(database.AccountAliasKey(normalizedAlias)); existed != nil {
+       if existed := m.store.GetAccountByAccountAlias(normalizedAlias); existed != nil {
                return ErrDuplicateAlias
        }
 
@@ -205,11 +207,12 @@ func (m *Manager) UpdateAccountAlias(accountID string, newAlias string) (err err
                return ErrMarshalAccount
        }
 
-       storeBatch := m.db.NewBatch()
-       storeBatch.Delete(database.AccountAliasKey(oldAlias))
-       storeBatch.Set(database.AccountIDKey(accountID), rawAccount)
-       storeBatch.Set(database.AccountAliasKey(normalizedAlias), []byte(accountID))
-       storeBatch.Write()
+       m.store.InitBatch()
+       defer m.store.CommitBatch()
+
+       m.store.DeleteAccountByAccountAlias(oldAlias)
+       m.store.SetAccount(accountID, normalizedAlias, rawAccount)
+
        return nil
 }
 
@@ -276,29 +279,30 @@ func (m *Manager) deleteAccountControlPrograms(accountID string) error {
        for _, cp := range cps {
                if cp.AccountID == accountID {
                        sha3pool.Sum256(hash[:], cp.ControlProgram)
-                       m.db.Delete(database.ContractKey(hash))
+                       m.store.DeleteRawProgram(hash)
                }
        }
-       m.db.Delete(database.Bip44ContractIndexKey(accountID, false))
-       m.db.Delete(database.Bip44ContractIndexKey(accountID, true))
-       m.db.Delete(database.ContractIndexKey(accountID))
+
+       m.store.DeleteBip44ContractIndex(accountID)
+       m.store.DeleteContractIndex(accountID)
+
        return nil
 }
 
 // deleteAccountUtxos deletes utxos matching accountID
 func (m *Manager) deleteAccountUtxos(accountID string) error {
-       accountUtxoIter := m.db.IteratorPrefix([]byte(UTXOPreFix))
-       defer accountUtxoIter.Release()
-       for accountUtxoIter.Next() {
-               accountUtxo := &UTXO{}
-               if err := json.Unmarshal(accountUtxoIter.Value(), accountUtxo); err != nil {
+       rawUTXOs := m.store.GetAccountUTXOs(accountID)
+
+       for _, rawUTXO := range rawUTXOs {
+               utxo := new(UTXO)
+               if err := json.Unmarshal(rawUTXO, utxo); err != nil {
                        return err
                }
-
-               if accountID == accountUtxo.AccountID {
-                       m.db.Delete(StandardUTXOKey(accountUtxo.OutputID))
+               if accountID == utxo.AccountID {
+                       m.store.DeleteUTXO(utxo.OutputID)
                }
        }
+
        return nil
 }
 
@@ -323,10 +327,11 @@ func (m *Manager) DeleteAccount(accountID string) (err error) {
        m.aliasCache.Remove(account.Alias)
        m.cacheMu.Unlock()
 
-       storeBatch := m.db.NewBatch()
-       storeBatch.Delete(database.AccountAliasKey(account.Alias))
-       storeBatch.Delete(database.AccountIDKey(account.ID))
-       storeBatch.Write()
+       m.store.InitBatch()
+       defer m.store.CommitBatch()
+
+       m.store.DeleteAccountByAccountAlias(account.Alias)
+       m.store.DeleteAccountByAccountID(account.ID)
        return nil
 }
 
@@ -339,7 +344,7 @@ func (m *Manager) FindByAlias(alias string) (*Account, error) {
                return m.FindByID(cachedID.(string))
        }
 
-       rawID := m.db.Get(database.AccountAliasKey(alias))
+       rawID := m.store.GetAccountByAccountAlias(alias)
        if rawID == nil {
                return nil, ErrFindAccount
        }
@@ -360,7 +365,7 @@ func (m *Manager) FindByID(id string) (*Account, error) {
                return cachedAccount.(*Account), nil
        }
 
-       rawAccount := m.db.Get(database.AccountIDKey(id))
+       rawAccount := m.store.GetAccountByAccountID(id)
        if rawAccount == nil {
                return nil, ErrFindAccount
        }
@@ -378,7 +383,7 @@ func (m *Manager) FindByID(id string) (*Account, error) {
 
 // GetAccountByProgram return Account by given CtrlProgram
 func (m *Manager) GetAccountByProgram(program *CtrlProgram) (*Account, error) {
-       rawAccount := m.db.Get(database.AccountIDKey(program.AccountID))
+       rawAccount := m.store.GetAccountByAccountID(program.AccountID)
        if rawAccount == nil {
                return nil, ErrFindAccount
        }
@@ -404,7 +409,7 @@ func (m *Manager) GetAccountByXPubsIndex(xPubs []chainkd.XPub, index uint64) (*A
 
 // GetAliasByID return the account alias by given ID
 func (m *Manager) GetAliasByID(id string) string {
-       rawAccount := m.db.Get(database.AccountIDKey(id))
+       rawAccount := m.store.GetAccountByAccountID(id)
        if rawAccount == nil {
                log.Warn("GetAliasByID fail to find account")
                return ""
@@ -418,7 +423,7 @@ func (m *Manager) GetAliasByID(id string) string {
 }
 
 func (m *Manager) GetCoinbaseArbitrary() []byte {
-       if arbitrary := m.db.Get([]byte(database.CoinbaseAbKey)); arbitrary != nil {
+       if arbitrary := m.store.GetCoinbaseArbitrary(); arbitrary != nil {
                return arbitrary
        }
        return []byte{}
@@ -439,19 +444,18 @@ func (m *Manager) GetCoinbaseControlProgram() ([]byte, error) {
 
 // GetCoinbaseCtrlProgram will return the coinbase CtrlProgram
 func (m *Manager) GetCoinbaseCtrlProgram() (*CtrlProgram, error) {
-       if data := m.db.Get([]byte(database.MiningAddressKey)); data != nil {
+       if data := m.store.GetMiningAddress(); data != nil {
                cp := &CtrlProgram{}
                return cp, json.Unmarshal(data, cp)
        }
 
-       accountIter := m.db.IteratorPrefix([]byte(database.AccountPrefix))
-       defer accountIter.Release()
-       if !accountIter.Next() {
-               return nil, ErrFindAccount
+       fistAccount, err := m.store.GetFirstAccount()
+       if err != nil {
+               return nil, err
        }
 
        account := &Account{}
-       if err := json.Unmarshal(accountIter.Value(), account); err != nil {
+       if err := json.Unmarshal(fistAccount, account); err != nil {
                return nil, err
        }
 
@@ -465,14 +469,15 @@ func (m *Manager) GetCoinbaseCtrlProgram() (*CtrlProgram, error) {
                return nil, err
        }
 
-       m.db.Set([]byte(database.MiningAddressKey), rawCP)
+       m.store.SetMiningAddress(rawCP)
+
        return program, nil
 }
 
 // GetContractIndex return the current index
 func (m *Manager) GetContractIndex(accountID string) uint64 {
        index := uint64(0)
-       if rawIndexBytes := m.db.Get(database.ContractIndexKey(accountID)); rawIndexBytes != nil {
+       if rawIndexBytes := m.store.GetContractIndex(accountID); rawIndexBytes != nil {
                index = common.BytesToUnit64(rawIndexBytes)
        }
        return index
@@ -481,7 +486,7 @@ func (m *Manager) GetContractIndex(accountID string) uint64 {
 // GetBip44ContractIndex return the current bip44 contract index
 func (m *Manager) GetBip44ContractIndex(accountID string, change bool) uint64 {
        index := uint64(0)
-       if rawIndexBytes := m.db.Get(database.Bip44ContractIndexKey(accountID, change)); rawIndexBytes != nil {
+       if rawIndexBytes := m.store.GetBip44ContractIndex(accountID, change); rawIndexBytes != nil {
                index = common.BytesToUnit64(rawIndexBytes)
        }
        return index
@@ -496,7 +501,7 @@ func (m *Manager) GetLocalCtrlProgramByAddress(address string) (*CtrlProgram, er
 
        var hash [32]byte
        sha3pool.Sum256(hash[:], program)
-       rawProgram := m.db.Get(database.ContractKey(hash))
+       rawProgram := m.store.GetRawProgram(hash)
        if rawProgram == nil {
                return nil, ErrFindCtrlProgram
        }
@@ -518,40 +523,43 @@ func (m *Manager) GetMiningAddress() (string, error) {
 func (m *Manager) IsLocalControlProgram(prog []byte) bool {
        var hash common.Hash
        sha3pool.Sum256(hash[:], prog)
-       bytes := m.db.Get(database.ContractKey(hash))
+       bytes := m.store.GetRawProgram(hash)
        return bytes != nil
 }
 
 // ListAccounts will return the accounts in the db
 func (m *Manager) ListAccounts(id string) ([]*Account, error) {
-       accounts := []*Account{}
-       accountIter := m.db.IteratorPrefix(database.AccountIDKey(strings.TrimSpace(id)))
-       defer accountIter.Release()
+       rawAccounts := m.store.GetAccounts(id)
 
-       for accountIter.Next() {
-               account := &Account{}
-               if err := json.Unmarshal(accountIter.Value(), &account); err != nil {
+       accounts := []*Account{}
+       for _, rawAccount := range rawAccounts {
+               account := new(Account)
+               if err := json.Unmarshal(rawAccount, &account); err != nil {
                        return nil, err
                }
                accounts = append(accounts, account)
        }
+
        return accounts, nil
 }
 
 // ListControlProgram return all the local control program
 func (m *Manager) ListControlProgram() ([]*CtrlProgram, error) {
-       cps := []*CtrlProgram{}
-       cpIter := m.db.IteratorPrefix([]byte(database.ContractPrefix))
-       defer cpIter.Release()
+       rawControlPrograms, err := m.store.GetControlPrograms()
+       if err != nil {
+               return nil, err
+       }
 
-       for cpIter.Next() {
-               cp := &CtrlProgram{}
-               if err := json.Unmarshal(cpIter.Value(), cp); err != nil {
+       controlPrograms := []*CtrlProgram{}
+       for _, rawControlProgram := range rawControlPrograms {
+               controlProgram := new(CtrlProgram)
+               if err := json.Unmarshal(rawControlProgram, controlProgram); err != nil {
                        return nil, err
                }
-               cps = append(cps, cp)
+               controlPrograms = append(controlPrograms, controlProgram)
        }
-       return cps, nil
+
+       return controlPrograms, nil
 }
 
 func (m *Manager) ListUnconfirmedUtxo(accountID string, isSmartContract bool) []*UTXO {
@@ -586,12 +594,12 @@ func (m *Manager) SetMiningAddress(miningAddress string) (string, error) {
                return "", err
        }
 
-       m.db.Set([]byte(database.MiningAddressKey), rawCP)
+       m.store.SetMiningAddress(rawCP)
        return m.GetMiningAddress()
 }
 
 func (m *Manager) SetCoinbaseArbitrary(arbitrary []byte) {
-       m.db.Set([]byte(database.CoinbaseAbKey), arbitrary)
+       m.store.SetCoinbaseArbitrary(arbitrary)
 }
 
 // CreateCtrlProgram generate an address for the select account
@@ -706,17 +714,18 @@ func (m *Manager) saveControlProgram(prog *CtrlProgram, updateIndex bool) error
                return err
        }
 
-       storeBatch := m.db.NewBatch()
-       storeBatch.Set(database.ContractKey(hash), accountCP)
+       m.store.InitBatch()
+       defer m.store.CommitBatch()
+
+       m.store.SetRawProgram(hash, accountCP)
        if updateIndex {
                switch acct.DeriveRule {
                case signers.BIP0032:
-                       storeBatch.Set(database.ContractIndexKey(acct.ID), common.Unit64ToBytes(prog.KeyIndex))
+                       m.store.SetContractIndex(acct.ID, prog.KeyIndex)
                case signers.BIP0044:
-                       storeBatch.Set(database.Bip44ContractIndexKey(acct.ID, prog.Change), common.Unit64ToBytes(prog.KeyIndex))
+                       m.store.SetBip44ContractIndex(acct.ID, prog.Change, prog.KeyIndex)
                }
        }
-       storeBatch.Write()
 
        return nil
 }
index dbc2655..d4b45fd 100644 (file)
@@ -31,7 +31,7 @@ func TestReserveBtmUtxoChain(t *testing.T) {
                        t.Fatal(err)
                }
 
-               m.db.Set(StandardUTXOKey(utxo.OutputID), data)
+               m.store.SetStandardUTXO(utxo.OutputID, data)
        }
 
        cases := []struct {
index 9957992..f3fd4d6 100644 (file)
@@ -5,7 +5,6 @@ import (
        "encoding/json"
 
        log "github.com/sirupsen/logrus"
-       "github.com/vapor/database"
 )
 
 // ImageSlice record info of single account
@@ -29,17 +28,16 @@ func (m *Manager) Backup() (*Image, error) {
        }
 
        // GetAccounts()
-       accountIter := m.db.IteratorPrefix([]byte(database.AccountPrefix))
-       defer accountIter.Release()
-       for accountIter.Next() {
-               a := &Account{}
-               if err := json.Unmarshal(accountIter.Value(), a); err != nil {
+       rawAccounts := m.store.GetAccounts("")
+
+       for _, rawAccount := range rawAccounts {
+               account := new(Account)
+               if err := json.Unmarshal(rawAccount, account); err != nil {
                        return nil, err
                }
-
                image.Slice = append(image.Slice, &ImageSlice{
-                       Account:       a,
-                       ContractIndex: m.GetContractIndex(a.ID),
+                       Account:       account,
+                       ContractIndex: m.GetContractIndex(account.ID),
                })
        }
        return image, nil
@@ -50,9 +48,11 @@ func (m *Manager) Restore(image *Image) error {
        m.accountMu.Lock()
        defer m.accountMu.Unlock()
 
-       storeBatch := m.db.NewBatch()
+       m.store.InitBatch()
+       defer m.store.CommitBatch()
+
        for _, slice := range image.Slice {
-               if existed := m.db.Get(database.AccountIDKey(slice.Account.ID)); existed != nil {
+               if existed := m.store.GetAccountByAccountID(slice.Account.ID); existed != nil {
                        log.WithFields(log.Fields{
                                "module": logModule,
                                "alias":  slice.Account.Alias,
@@ -60,7 +60,7 @@ func (m *Manager) Restore(image *Image) error {
                        }).Warning("skip restore account due to already existed")
                        continue
                }
-               if existed := m.db.Get(database.AccountAliasKey(slice.Account.Alias)); existed != nil {
+               if existed := m.store.GetAccountByAccountAlias(slice.Account.Alias); existed != nil {
                        return ErrDuplicateAlias
                }
 
@@ -69,10 +69,8 @@ func (m *Manager) Restore(image *Image) error {
                        return ErrMarshalAccount
                }
 
-               storeBatch.Set(database.AccountIDKey(slice.Account.ID), rawAccount)
-               storeBatch.Set(database.AccountAliasKey(slice.Account.Alias), []byte(slice.Account.ID))
+               m.store.SetAccount(slice.Account.ID, slice.Account.Alias, rawAccount)
        }
 
-       storeBatch.Write()
        return nil
 }
index dd96a7e..7e8b3de 100644 (file)
@@ -2,28 +2,8 @@ package account
 
 import (
        "github.com/vapor/blockchain/query"
-       "github.com/vapor/protocol/bc"
 )
 
-const (
-       //UTXOPreFix is StandardUTXOKey prefix
-       UTXOPreFix = "ACU:"
-       //SUTXOPrefix is ContractUTXOKey prefix
-       SUTXOPrefix = "SCU:"
-)
-
-// StandardUTXOKey makes an account unspent outputs key to store
-func StandardUTXOKey(id bc.Hash) []byte {
-       name := id.String()
-       return []byte(UTXOPreFix + name)
-}
-
-// ContractUTXOKey makes a smart contract unspent outputs key to store
-func ContractUTXOKey(id bc.Hash) []byte {
-       name := id.String()
-       return []byte(SUTXOPrefix + name)
-}
-
 //Annotated init an annotated account object
 func Annotated(a *Account) *query.AnnotatedAccount {
        return &query.AnnotatedAccount{
index ed4d685..a8a81f7 100644 (file)
@@ -11,7 +11,7 @@ import (
 
        log "github.com/sirupsen/logrus"
 
-       dbm "github.com/vapor/database/leveldb"
+       "github.com/vapor/database"
        "github.com/vapor/errors"
        "github.com/vapor/protocol/bc"
 )
@@ -56,7 +56,7 @@ type utxoKeeper struct {
        // `sync/atomic` expects the first word in an allocated struct to be 64-bit
        // aligned on both ARM and x86-32. See https://goo.gl/zW7dgq for more details.
        nextIndex     uint64
-       db            dbm.DB
+       store         database.AccountStorer
        mtx           sync.RWMutex
        currentHeight func() uint64
 
@@ -65,9 +65,9 @@ type utxoKeeper struct {
        reservations map[uint64]*reservation
 }
 
-func newUtxoKeeper(f func() uint64, walletdb dbm.DB) *utxoKeeper {
+func newUtxoKeeper(f func() uint64, store database.AccountStorer) *utxoKeeper {
        uk := &utxoKeeper{
-               db:            walletdb,
+               store:         store,
                currentHeight: f,
                unconfirmed:   make(map[bc.Hash]*UTXO),
                reserved:      make(map[bc.Hash]uint64),
@@ -223,16 +223,16 @@ func (uk *utxoKeeper) findUtxos(accountID string, assetID *bc.AssetID, useUnconf
                }
        }
 
-       utxoIter := uk.db.IteratorPrefix([]byte(UTXOPreFix))
-       defer utxoIter.Release()
-       for utxoIter.Next() {
-               u := &UTXO{}
-               if err := json.Unmarshal(utxoIter.Value(), u); err != nil {
+       rawUTXOs := uk.store.GetUTXOs()
+       for _, rawUTXO := range rawUTXOs {
+               utxo := new(UTXO)
+               if err := json.Unmarshal(rawUTXO, utxo); err != nil {
                        log.WithFields(log.Fields{"module": logModule, "err": err}).Error("utxoKeeper findUtxos fail on unmarshal utxo")
                        continue
                }
-               appendUtxo(u)
+               appendUtxo(utxo)
        }
+
        if !useUnconfirmed {
                return utxos, immatureAmount
        }
@@ -249,10 +249,10 @@ func (uk *utxoKeeper) findUtxo(outHash bc.Hash, useUnconfirmed bool) (*UTXO, err
        }
 
        u := &UTXO{}
-       if data := uk.db.Get(StandardUTXOKey(outHash)); data != nil {
+       if data := uk.store.GetStandardUTXO(outHash); data != nil {
                return u, json.Unmarshal(data, u)
        }
-       if data := uk.db.Get(ContractUTXOKey(outHash)); data != nil {
+       if data := uk.store.GetContractUTXO(outHash); data != nil {
                return u, json.Unmarshal(data, u)
        }
        return nil, ErrMatchUTXO
index 6cd4879..55f6559 100644 (file)
@@ -6,6 +6,8 @@ import (
        "testing"
        "time"
 
+       "github.com/vapor/database"
+
        dbm "github.com/vapor/database/leveldb"
        "github.com/vapor/protocol/bc"
        "github.com/vapor/testutil"
@@ -288,13 +290,13 @@ func TestReserve(t *testing.T) {
        }{
                {
                        before: utxoKeeper{
-                               db:            testDB,
+                               store:         database.NewAccountStore(testDB),
                                currentHeight: currentHeight,
                                reserved:      map[bc.Hash]uint64{},
                                reservations:  map[uint64]*reservation{},
                        },
                        after: utxoKeeper{
-                               db:            testDB,
+                               store:         database.NewAccountStore(testDB),
                                currentHeight: currentHeight,
                                reserved:      map[bc.Hash]uint64{},
                                reservations:  map[uint64]*reservation{},
@@ -304,7 +306,7 @@ func TestReserve(t *testing.T) {
                },
                {
                        before: utxoKeeper{
-                               db:            testDB,
+                               store:         database.NewAccountStore(testDB),
                                currentHeight: currentHeight,
                                unconfirmed: map[bc.Hash]*UTXO{
                                        bc.NewHash([32]byte{0x01}): &UTXO{
@@ -317,7 +319,7 @@ func TestReserve(t *testing.T) {
                                reservations: map[uint64]*reservation{},
                        },
                        after: utxoKeeper{
-                               db:            testDB,
+                               store:         database.NewAccountStore(testDB),
                                currentHeight: currentHeight,
                                unconfirmed: map[bc.Hash]*UTXO{
                                        bc.NewHash([32]byte{0x01}): &UTXO{
@@ -334,7 +336,7 @@ func TestReserve(t *testing.T) {
                },
                {
                        before: utxoKeeper{
-                               db:            testDB,
+                               store:         database.NewAccountStore(testDB),
                                currentHeight: currentHeight,
                                unconfirmed: map[bc.Hash]*UTXO{
                                        bc.NewHash([32]byte{0x01}): &UTXO{
@@ -348,7 +350,7 @@ func TestReserve(t *testing.T) {
                                reservations: map[uint64]*reservation{},
                        },
                        after: utxoKeeper{
-                               db:            testDB,
+                               store:         database.NewAccountStore(testDB),
                                currentHeight: currentHeight,
                                unconfirmed: map[bc.Hash]*UTXO{
                                        bc.NewHash([32]byte{0x01}): &UTXO{
@@ -366,7 +368,7 @@ func TestReserve(t *testing.T) {
                },
                {
                        before: utxoKeeper{
-                               db:            testDB,
+                               store:         database.NewAccountStore(testDB),
                                currentHeight: currentHeight,
                                unconfirmed: map[bc.Hash]*UTXO{
                                        bc.NewHash([32]byte{0x01}): &UTXO{
@@ -381,7 +383,7 @@ func TestReserve(t *testing.T) {
                                reservations: map[uint64]*reservation{},
                        },
                        after: utxoKeeper{
-                               db:            testDB,
+                               store:         database.NewAccountStore(testDB),
                                currentHeight: currentHeight,
                                unconfirmed: map[bc.Hash]*UTXO{
                                        bc.NewHash([32]byte{0x01}): &UTXO{
@@ -400,7 +402,7 @@ func TestReserve(t *testing.T) {
                },
                {
                        before: utxoKeeper{
-                               db:            testDB,
+                               store:         database.NewAccountStore(testDB),
                                currentHeight: currentHeight,
                                unconfirmed: map[bc.Hash]*UTXO{
                                        bc.NewHash([32]byte{0x01}): &UTXO{
@@ -413,7 +415,7 @@ func TestReserve(t *testing.T) {
                                reservations: map[uint64]*reservation{},
                        },
                        after: utxoKeeper{
-                               db:            testDB,
+                               store:         database.NewAccountStore(testDB),
                                currentHeight: currentHeight,
                                unconfirmed: map[bc.Hash]*UTXO{
                                        bc.NewHash([32]byte{0x01}): &UTXO{
@@ -446,7 +448,7 @@ func TestReserve(t *testing.T) {
                },
                {
                        before: utxoKeeper{
-                               db:            testDB,
+                               store:         database.NewAccountStore(testDB),
                                currentHeight: currentHeight,
                                nextIndex:     1,
                                unconfirmed: map[bc.Hash]*UTXO{
@@ -472,7 +474,7 @@ func TestReserve(t *testing.T) {
                                reservations: map[uint64]*reservation{},
                        },
                        after: utxoKeeper{
-                               db:            testDB,
+                               store:         database.NewAccountStore(testDB),
                                currentHeight: currentHeight,
                                unconfirmed: map[bc.Hash]*UTXO{
                                        bc.NewHash([32]byte{0x01}): &UTXO{
@@ -522,7 +524,7 @@ func TestReserve(t *testing.T) {
                },
                {
                        before: utxoKeeper{
-                               db:            testDB,
+                               store:         database.NewAccountStore(testDB),
                                currentHeight: currentHeight,
                                unconfirmed: map[bc.Hash]*UTXO{
                                        bc.NewHash([32]byte{0x01}): &UTXO{
@@ -536,7 +538,7 @@ func TestReserve(t *testing.T) {
                                reservations: map[uint64]*reservation{},
                        },
                        after: utxoKeeper{
-                               db:            testDB,
+                               store:         database.NewAccountStore(testDB),
                                currentHeight: currentHeight,
                                unconfirmed: map[bc.Hash]*UTXO{
                                        bc.NewHash([32]byte{0x01}): &UTXO{
@@ -594,7 +596,7 @@ func TestReserveParticular(t *testing.T) {
        }{
                {
                        before: utxoKeeper{
-                               db:            testDB,
+                               store:         database.NewAccountStore(testDB),
                                currentHeight: currentHeight,
                                unconfirmed: map[bc.Hash]*UTXO{
                                        bc.NewHash([32]byte{0x01}): &UTXO{
@@ -609,7 +611,7 @@ func TestReserveParticular(t *testing.T) {
                                reservations: map[uint64]*reservation{},
                        },
                        after: utxoKeeper{
-                               db:            testDB,
+                               store:         database.NewAccountStore(testDB),
                                currentHeight: currentHeight,
                                unconfirmed: map[bc.Hash]*UTXO{
                                        bc.NewHash([32]byte{0x01}): &UTXO{
@@ -628,7 +630,7 @@ func TestReserveParticular(t *testing.T) {
                },
                {
                        before: utxoKeeper{
-                               db:            testDB,
+                               store:         database.NewAccountStore(testDB),
                                currentHeight: currentHeight,
                                unconfirmed: map[bc.Hash]*UTXO{
                                        bc.NewHash([32]byte{0x01}): &UTXO{
@@ -642,7 +644,7 @@ func TestReserveParticular(t *testing.T) {
                                reservations: map[uint64]*reservation{},
                        },
                        after: utxoKeeper{
-                               db:            testDB,
+                               store:         database.NewAccountStore(testDB),
                                currentHeight: currentHeight,
                                unconfirmed: map[bc.Hash]*UTXO{
                                        bc.NewHash([32]byte{0x01}): &UTXO{
@@ -660,7 +662,7 @@ func TestReserveParticular(t *testing.T) {
                },
                {
                        before: utxoKeeper{
-                               db:            testDB,
+                               store:         database.NewAccountStore(testDB),
                                currentHeight: currentHeight,
                                unconfirmed: map[bc.Hash]*UTXO{
                                        bc.NewHash([32]byte{0x01}): &UTXO{
@@ -673,7 +675,7 @@ func TestReserveParticular(t *testing.T) {
                                reservations: map[uint64]*reservation{},
                        },
                        after: utxoKeeper{
-                               db:            testDB,
+                               store:         database.NewAccountStore(testDB),
                                currentHeight: currentHeight,
                                unconfirmed: map[bc.Hash]*UTXO{
                                        bc.NewHash([32]byte{0x01}): &UTXO{
@@ -753,7 +755,7 @@ func TestFindUtxos(t *testing.T) {
        }{
                {
                        uk: utxoKeeper{
-                               db:            testDB,
+                               store:         database.NewAccountStore(testDB),
                                currentHeight: currentHeight,
                                unconfirmed:   map[bc.Hash]*UTXO{},
                        },
@@ -764,7 +766,7 @@ func TestFindUtxos(t *testing.T) {
                },
                {
                        uk: utxoKeeper{
-                               db:            testDB,
+                               store:         database.NewAccountStore(testDB),
                                currentHeight: currentHeight,
                                unconfirmed:   map[bc.Hash]*UTXO{},
                        },
@@ -793,7 +795,7 @@ func TestFindUtxos(t *testing.T) {
                },
                {
                        uk: utxoKeeper{
-                               db:            testDB,
+                               store:         database.NewAccountStore(testDB),
                                currentHeight: currentHeight,
                                unconfirmed:   map[bc.Hash]*UTXO{},
                        },
@@ -811,7 +813,7 @@ func TestFindUtxos(t *testing.T) {
                },
                {
                        uk: utxoKeeper{
-                               db:            testDB,
+                               store:         database.NewAccountStore(testDB),
                                currentHeight: currentHeight,
                                unconfirmed: map[bc.Hash]*UTXO{
                                        bc.NewHash([32]byte{0x01}): &UTXO{
@@ -840,7 +842,7 @@ func TestFindUtxos(t *testing.T) {
                },
                {
                        uk: utxoKeeper{
-                               db:            testDB,
+                               store:         database.NewAccountStore(testDB),
                                currentHeight: currentHeight,
                                unconfirmed: map[bc.Hash]*UTXO{
                                        bc.NewHash([32]byte{0x11}): &UTXO{
@@ -874,7 +876,7 @@ func TestFindUtxos(t *testing.T) {
                },
                {
                        uk: utxoKeeper{
-                               db:            testDB,
+                               store:         database.NewAccountStore(testDB),
                                currentHeight: currentHeight,
                                unconfirmed: map[bc.Hash]*UTXO{
                                        bc.NewHash([32]byte{0x01}): &UTXO{
@@ -918,7 +920,7 @@ func TestFindUtxos(t *testing.T) {
                },
                {
                        uk: utxoKeeper{
-                               db:            testDB,
+                               store:         database.NewAccountStore(testDB),
                                currentHeight: currentHeight,
                                unconfirmed:   map[bc.Hash]*UTXO{},
                        },
@@ -950,7 +952,7 @@ func TestFindUtxos(t *testing.T) {
                        if err != nil {
                                t.Error(err)
                        }
-                       testDB.Set(StandardUTXOKey(u.OutputID), data)
+                       testDB.Set(database.StandardUTXOKey(u.OutputID), data)
                }
 
                gotUtxos, immatureAmount := c.uk.findUtxos("testAccount", &bc.AssetID{}, c.useUnconfirmed, c.vote)
@@ -962,7 +964,7 @@ func TestFindUtxos(t *testing.T) {
                }
 
                for _, u := range c.dbUtxos {
-                       testDB.Delete(StandardUTXOKey(u.OutputID))
+                       testDB.Delete(database.StandardUTXOKey(u.OutputID))
                }
        }
 }
@@ -982,7 +984,7 @@ func TestFindUtxo(t *testing.T) {
        }{
                {
                        uk: utxoKeeper{
-                               db:            testDB,
+                               store:         database.NewAccountStore(testDB),
                                currentHeight: currentHeight,
                                unconfirmed:   map[bc.Hash]*UTXO{},
                        },
@@ -993,7 +995,7 @@ func TestFindUtxo(t *testing.T) {
                },
                {
                        uk: utxoKeeper{
-                               db:            testDB,
+                               store:         database.NewAccountStore(testDB),
                                currentHeight: currentHeight,
                                unconfirmed: map[bc.Hash]*UTXO{
                                        bc.NewHash([32]byte{0x01}): &UTXO{OutputID: bc.NewHash([32]byte{0x01})},
@@ -1007,7 +1009,7 @@ func TestFindUtxo(t *testing.T) {
                },
                {
                        uk: utxoKeeper{
-                               db:            testDB,
+                               store:         database.NewAccountStore(testDB),
                                currentHeight: currentHeight,
                                unconfirmed: map[bc.Hash]*UTXO{
                                        bc.NewHash([32]byte{0x01}): &UTXO{OutputID: bc.NewHash([32]byte{0x01})},
@@ -1021,12 +1023,12 @@ func TestFindUtxo(t *testing.T) {
                },
                {
                        uk: utxoKeeper{
-                               db:            testDB,
+                               store:         database.NewAccountStore(testDB),
                                currentHeight: currentHeight,
                                unconfirmed:   map[bc.Hash]*UTXO{},
                        },
                        dbUtxos: map[string]*UTXO{
-                               string(StandardUTXOKey(bc.NewHash([32]byte{0x01}))): &UTXO{OutputID: bc.NewHash([32]byte{0x01})},
+                               string(database.StandardUTXOKey(bc.NewHash([32]byte{0x01}))): &UTXO{OutputID: bc.NewHash([32]byte{0x01})},
                        },
                        outHash:        bc.NewHash([32]byte{0x01}),
                        wantUtxo:       &UTXO{OutputID: bc.NewHash([32]byte{0x01})},
@@ -1035,12 +1037,12 @@ func TestFindUtxo(t *testing.T) {
                },
                {
                        uk: utxoKeeper{
-                               db:            testDB,
+                               store:         database.NewAccountStore(testDB),
                                currentHeight: currentHeight,
                                unconfirmed:   map[bc.Hash]*UTXO{},
                        },
                        dbUtxos: map[string]*UTXO{
-                               string(ContractUTXOKey(bc.NewHash([32]byte{0x01}))): &UTXO{OutputID: bc.NewHash([32]byte{0x01})},
+                               string(database.ContractUTXOKey(bc.NewHash([32]byte{0x01}))): &UTXO{OutputID: bc.NewHash([32]byte{0x01})},
                        },
                        outHash:        bc.NewHash([32]byte{0x01}),
                        wantUtxo:       &UTXO{OutputID: bc.NewHash([32]byte{0x01})},
@@ -1067,7 +1069,7 @@ func TestFindUtxo(t *testing.T) {
                }
 
                for _, u := range c.dbUtxos {
-                       testDB.Delete(StandardUTXOKey(u.OutputID))
+                       testDB.Delete(database.StandardUTXOKey(u.OutputID))
                }
        }
 }
index 44976e1..5c7e21e 100644 (file)
@@ -11,10 +11,12 @@ import (
 
 // AccountStorer interface contains account storage functions.
 type AccountStorer interface {
+       InitBatch()
+       CommitBatch()
        SetAccount(string, string, []byte)
        SetAccountIndex([]chainkd.XPub, uint64)
        GetAccountByAccountAlias(string) []byte
-       GetAccountByAccountID(string) []byte // duplicate in WalletStorer
+       GetAccountByAccountID(string) []byte
        GetAccountIndex([]chainkd.XPub) []byte
        DeleteAccountByAccountAlias(string)
        DeleteAccountByAccountID(string)
@@ -23,21 +25,24 @@ type AccountStorer interface {
        DeleteContractIndex(string)
        GetContractIndex(string) []byte
        // DeleteAccountUTXOs(string) error
+       GetAccountUTXOs(string) [][]byte
+       DeleteUTXO(bc.Hash)
        GetCoinbaseArbitrary() []byte
        SetCoinbaseArbitrary([]byte)
        GetMiningAddress() []byte
        GetFirstAccount() ([]byte, error)
        SetMiningAddress([]byte)
        GetBip44ContractIndex(string, bool) []byte
-       GetRawProgram(common.Hash) []byte // duplicate in WalletStorer
-       GetAccounts(string) ([][]byte, error)
+       GetRawProgram(common.Hash) []byte
+       GetAccounts(string) [][]byte
        GetControlPrograms() ([][]byte, error)
        SetRawProgram(common.Hash, []byte)
        SetContractIndex(string, uint64)
        SetBip44ContractIndex(string, bool, uint64)
-       GetUTXOs(string) [][]byte
-       GetStandardUTXO(bc.Hash) []byte // duplicate in WalletStorer
+       GetUTXOs() [][]byte
+       GetStandardUTXO(bc.Hash) []byte
        GetContractUTXO(bc.Hash) []byte
+       SetStandardUTXO(bc.Hash, []byte)
 }
 
 // AccountStore satisfies AccountStorer interface.
@@ -54,17 +59,54 @@ func NewAccountStore(db dbm.DB) *AccountStore {
        }
 }
 
+// InitBatch initial batch
+func (store *AccountStore) InitBatch() {
+       if store.batch == nil {
+               store.batch = store.accountDB.NewBatch()
+       }
+}
+
+// CommitBatch commit batch
+func (store *AccountStore) CommitBatch() {
+       if store.batch != nil {
+               store.batch.Write()
+               store.batch = nil
+       }
+}
+
 // SetAccount set account account ID, account alias and raw account.
 func (store *AccountStore) SetAccount(accountID, accountAlias string, rawAccount []byte) {
        batch := store.accountDB.NewBatch()
+       if store.batch != nil {
+               batch = store.batch
+       }
        batch.Set(AccountIDKey(accountID), rawAccount)
        batch.Set(AccountAliasKey(accountAlias), []byte(accountID))
-       batch.Write()
+       if store.batch == nil {
+               batch.Write()
+       }
+}
+
+// DeleteAccount set account account ID, account alias and raw account.
+func (store *AccountStore) DeleteAccount(accountID, accountAlias string) {
+       batch := store.accountDB.NewBatch()
+       if store.batch != nil {
+               batch = store.batch
+       }
+       batch.Delete(AccountIDKey(accountID))
+       batch.Delete(AccountAliasKey(accountAlias))
+       if store.batch == nil {
+               batch.Write()
+       }
 }
 
 // SetAccountIndex set account index
 func (store *AccountStore) SetAccountIndex(xpubs []chainkd.XPub, keyIndex uint64) {
-       store.accountDB.Set(AccountIndexKey(xpubs), common.Unit64ToBytes(keyIndex))
+       if store.batch == nil {
+               store.accountDB.Set(AccountIndexKey(xpubs), common.Unit64ToBytes(keyIndex))
+       } else {
+               store.batch.Set(AccountIndexKey(xpubs), common.Unit64ToBytes(keyIndex))
+       }
 }
 
 // GetAccountByAccountAlias get account by account alias
@@ -84,30 +126,51 @@ func (store *AccountStore) GetAccountIndex(xpubs []chainkd.XPub) []byte {
 
 // DeleteAccountByAccountAlias delete account by account alias
 func (store *AccountStore) DeleteAccountByAccountAlias(accountAlias string) {
-       store.accountDB.Delete(AccountAliasKey(accountAlias))
+       if store.batch == nil {
+               store.accountDB.Delete(AccountAliasKey(accountAlias))
+       } else {
+               store.batch.Delete(AccountAliasKey(accountAlias))
+       }
 }
 
 // DeleteAccountByAccountID delete account by accountID
 func (store *AccountStore) DeleteAccountByAccountID(accountID string) {
-       store.accountDB.Delete(AccountIDKey(accountID))
+       if store.batch == nil {
+               store.accountDB.Delete(AccountIDKey(accountID))
+       } else {
+               store.batch.Delete(AccountIDKey(accountID))
+       }
 }
 
 // DeleteRawProgram delete raw control program by hash
 func (store *AccountStore) DeleteRawProgram(hash common.Hash) {
-       store.accountDB.Delete(ContractKey(hash))
+       if store.batch == nil {
+               store.accountDB.Delete(ContractKey(hash))
+       } else {
+               store.batch.Delete(ContractKey(hash))
+       }
 }
 
 // DeleteBip44ContractIndex delete bip44 contract index by accountID
 func (store *AccountStore) DeleteBip44ContractIndex(accountID string) {
        batch := store.accountDB.NewBatch()
+       if store.batch != nil {
+               batch = store.batch
+       }
        batch.Delete(Bip44ContractIndexKey(accountID, false))
        batch.Delete(Bip44ContractIndexKey(accountID, true))
-       batch.Write()
+       if store.batch == nil {
+               batch.Write()
+       }
 }
 
 // DeleteContractIndex delete contract index by accountID
 func (store *AccountStore) DeleteContractIndex(accountID string) {
-       store.accountDB.Delete(ContractIndexKey(accountID))
+       if store.batch == nil {
+               store.accountDB.Delete(ContractIndexKey(accountID))
+       } else {
+               store.batch.Delete(ContractIndexKey(accountID))
+       }
 }
 
 // GetContractIndex get contract index
@@ -115,22 +178,26 @@ func (store *AccountStore) GetContractIndex(accountID string) []byte {
        return store.accountDB.Get(ContractIndexKey(accountID))
 }
 
-// // DeleteAccountUTXOs delete account utxos by accountID
-// func (store *AccountStore) DeleteAccountUTXOs(accountID string) error {
-//     accountUtxoIter := store.accountDB.IteratorPrefix([]byte(UTXOPrefix))
-//     defer accountUtxoIter.Release()
-//     for accountUtxoIter.Next() {
-//             accountUtxo := &UTXO{}
-//             if err := json.Unmarshal(accountUtxoIter.Value(), accountUtxo); err != nil {
-//                     return err
-//             }
+// GetAccountUTXOs get account utxos by account id
+func (store *AccountStore) GetAccountUTXOs(accountID string) [][]byte {
+       accountUtxoIter := store.accountDB.IteratorPrefix([]byte(UTXOPrefix))
+       defer accountUtxoIter.Release()
+
+       utxos := make([][]byte, 0)
+       for accountUtxoIter.Next() {
+               utxos = append(utxos, accountUtxoIter.Value())
+       }
+       return utxos
+}
 
-//             if accountID == accountUtxo.AccountID {
-//                     store.accountDB.Delete(StandardUTXOKey(accountUtxo.OutputID))
-//             }
-//     }
-//     return nil
-// }
+// DeleteUTXO delete utxo by outpu id
+func (store *AccountStore) DeleteUTXO(outputID bc.Hash) {
+       if store.batch == nil {
+               store.accountDB.Delete(StandardUTXOKey(outputID))
+       } else {
+               store.batch.Delete(StandardUTXOKey(outputID))
+       }
+}
 
 // GetCoinbaseArbitrary get coinbase arbitrary
 func (store *AccountStore) GetCoinbaseArbitrary() []byte {
@@ -139,7 +206,11 @@ func (store *AccountStore) GetCoinbaseArbitrary() []byte {
 
 // SetCoinbaseArbitrary set coinbase arbitrary
 func (store *AccountStore) SetCoinbaseArbitrary(arbitrary []byte) {
-       store.accountDB.Set([]byte(CoinbaseAbKey), arbitrary)
+       if store.batch == nil {
+               store.accountDB.Set([]byte(CoinbaseAbKey), arbitrary)
+       } else {
+               store.batch.Set([]byte(CoinbaseAbKey), arbitrary)
+       }
 }
 
 // GetMiningAddress get mining address
@@ -151,6 +222,7 @@ func (store *AccountStore) GetMiningAddress() []byte {
 func (store *AccountStore) GetFirstAccount() ([]byte, error) {
        accountIter := store.accountDB.IteratorPrefix([]byte(AccountPrefix))
        defer accountIter.Release()
+
        if !accountIter.Next() {
                return nil, ErrFindAccount
        }
@@ -159,7 +231,11 @@ func (store *AccountStore) GetFirstAccount() ([]byte, error) {
 
 // SetMiningAddress set mining address
 func (store *AccountStore) SetMiningAddress(rawProgram []byte) {
-       store.accountDB.Set([]byte(MiningAddressKey), rawProgram)
+       if store.batch == nil {
+               store.accountDB.Set([]byte(MiningAddressKey), rawProgram)
+       } else {
+               store.batch.Set([]byte(MiningAddressKey), rawProgram)
+       }
 }
 
 // GetBip44ContractIndex get bip44 contract index
@@ -173,23 +249,23 @@ func (store *AccountStore) GetRawProgram(hash common.Hash) []byte {
 }
 
 // GetAccounts get all accounts which name prfix is id.
-func (store *AccountStore) GetAccounts(id string) ([][]byte, error) {
-       accounts := make([][]byte, 0)
+func (store *AccountStore) GetAccounts(id string) [][]byte {
        accountIter := store.accountDB.IteratorPrefix(AccountIDKey(strings.TrimSpace(id)))
        defer accountIter.Release()
 
+       accounts := make([][]byte, 0)
        for accountIter.Next() {
                accounts = append(accounts, accountIter.Value())
        }
-       return accounts, nil
+       return accounts
 }
 
 // GetControlPrograms get all local control programs
 func (store *AccountStore) GetControlPrograms() ([][]byte, error) {
-       cps := make([][]byte, 0)
        cpIter := store.accountDB.IteratorPrefix([]byte(ContractPrefix))
        defer cpIter.Release()
 
+       cps := make([][]byte, 0)
        for cpIter.Next() {
                cps = append(cps, cpIter.Value())
        }
@@ -198,25 +274,37 @@ func (store *AccountStore) GetControlPrograms() ([][]byte, error) {
 
 // SetRawProgram set raw program
 func (store *AccountStore) SetRawProgram(hash common.Hash, program []byte) {
-       store.accountDB.Set(ContractKey(hash), program)
+       if store.batch == nil {
+               store.accountDB.Set(ContractKey(hash), program)
+       } else {
+               store.batch.Set(ContractKey(hash), program)
+       }
 }
 
 // SetContractIndex set contract index
 func (store *AccountStore) SetContractIndex(accountID string, index uint64) {
-       store.accountDB.Set(ContractIndexKey(accountID), common.Unit64ToBytes(index))
+       if store.batch == nil {
+               store.accountDB.Set(ContractIndexKey(accountID), common.Unit64ToBytes(index))
+       } else {
+               store.batch.Set(ContractIndexKey(accountID), common.Unit64ToBytes(index))
+       }
 }
 
 // SetBip44ContractIndex set contract index
 func (store *AccountStore) SetBip44ContractIndex(accountID string, change bool, index uint64) {
-       store.accountDB.Set(Bip44ContractIndexKey(accountID, change), common.Unit64ToBytes(index))
+       if store.batch == nil {
+               store.accountDB.Set(Bip44ContractIndexKey(accountID, change), common.Unit64ToBytes(index))
+       } else {
+               store.batch.Set(Bip44ContractIndexKey(accountID, change), common.Unit64ToBytes(index))
+       }
 }
 
 // GetUTXOs get utxos by accountID
-func (store *AccountStore) GetUTXOs(accountID string) [][]byte {
-       utxos := make([][]byte, 0)
+func (store *AccountStore) GetUTXOs() [][]byte {
        utxoIter := store.accountDB.IteratorPrefix([]byte(UTXOPrefix))
        defer utxoIter.Release()
 
+       utxos := make([][]byte, 0)
        for utxoIter.Next() {
                utxos = append(utxos, utxoIter.Value())
        }
@@ -232,3 +320,12 @@ func (store *AccountStore) GetStandardUTXO(outid bc.Hash) []byte {
 func (store *AccountStore) GetContractUTXO(outid bc.Hash) []byte {
        return store.accountDB.Get(ContractUTXOKey(outid))
 }
+
+// SetStandardUTXO set standard utxo
+func (store *AccountStore) SetStandardUTXO(outputID bc.Hash, data []byte) {
+       if store.batch == nil {
+               store.accountDB.Set(StandardUTXOKey(outputID), data)
+       } else {
+               store.batch.Set(StandardUTXOKey(outputID), data)
+       }
+}
index 78b6e0f..ce704dc 100644 (file)
@@ -9,6 +9,7 @@ import (
        "github.com/vapor/consensus"
        "github.com/vapor/consensus/segwit"
        "github.com/vapor/crypto/sha3pool"
+       "github.com/vapor/database"
        "github.com/vapor/errors"
        "github.com/vapor/protocol/bc"
        "github.com/vapor/protocol/bc/types"
@@ -16,9 +17,9 @@ import (
 
 // GetAccountUtxos return all account unspent outputs
 func (w *Wallet) GetAccountUtxos(accountID string, id string, unconfirmed, isSmartContract bool, vote bool) []*account.UTXO {
-       prefix := account.UTXOPreFix
+       prefix := database.UTXOPrefix
        if isSmartContract {
-               prefix = account.SUTXOPrefix
+               prefix = database.SUTXOPrefix
        }
 
        accountUtxos := []*account.UTXO{}
index 77b6f96..ad14a7a 100644 (file)
@@ -42,16 +42,16 @@ func TestGetAccountUtxos(t *testing.T) {
                },
                {
                        dbUtxos: map[string]*account.UTXO{
-                               string(account.StandardUTXOKey(bc.Hash{V0: 1})): &account.UTXO{
+                               string(database.StandardUTXOKey(bc.Hash{V0: 1})): &account.UTXO{
                                        OutputID: bc.Hash{V0: 1},
                                },
-                               string(account.StandardUTXOKey(bc.Hash{V0: 2})): &account.UTXO{
+                               string(database.StandardUTXOKey(bc.Hash{V0: 2})): &account.UTXO{
                                        OutputID: bc.Hash{V0: 2},
                                },
-                               string(account.StandardUTXOKey(bc.Hash{V0: 3})): &account.UTXO{
+                               string(database.StandardUTXOKey(bc.Hash{V0: 3})): &account.UTXO{
                                        OutputID: bc.Hash{V0: 3},
                                },
-                               string(account.ContractUTXOKey(bc.Hash{V0: 4})): &account.UTXO{
+                               string(database.ContractUTXOKey(bc.Hash{V0: 4})): &account.UTXO{
                                        OutputID: bc.Hash{V0: 4},
                                },
                        },
@@ -66,16 +66,16 @@ func TestGetAccountUtxos(t *testing.T) {
                },
                {
                        dbUtxos: map[string]*account.UTXO{
-                               string(account.StandardUTXOKey(bc.Hash{V0: 1})): &account.UTXO{
+                               string(database.StandardUTXOKey(bc.Hash{V0: 1})): &account.UTXO{
                                        OutputID: bc.Hash{V0: 1},
                                },
-                               string(account.StandardUTXOKey(bc.Hash{V0: 2})): &account.UTXO{
+                               string(database.StandardUTXOKey(bc.Hash{V0: 2})): &account.UTXO{
                                        OutputID: bc.Hash{V0: 2},
                                },
-                               string(account.StandardUTXOKey(bc.Hash{V0: 3})): &account.UTXO{
+                               string(database.StandardUTXOKey(bc.Hash{V0: 3})): &account.UTXO{
                                        OutputID: bc.Hash{V0: 3},
                                },
-                               string(account.ContractUTXOKey(bc.Hash{V0: 4})): &account.UTXO{
+                               string(database.ContractUTXOKey(bc.Hash{V0: 4})): &account.UTXO{
                                        OutputID: bc.Hash{V0: 4},
                                },
                        },
@@ -94,16 +94,16 @@ func TestGetAccountUtxos(t *testing.T) {
                },
                {
                        dbUtxos: map[string]*account.UTXO{
-                               string(account.StandardUTXOKey(bc.Hash{V0: 1})): &account.UTXO{
+                               string(database.StandardUTXOKey(bc.Hash{V0: 1})): &account.UTXO{
                                        OutputID: bc.Hash{V0: 1},
                                },
-                               string(account.StandardUTXOKey(bc.Hash{V0: 1, V1: 2})): &account.UTXO{
+                               string(database.StandardUTXOKey(bc.Hash{V0: 1, V1: 2})): &account.UTXO{
                                        OutputID: bc.Hash{V0: 1, V1: 2},
                                },
-                               string(account.StandardUTXOKey(bc.Hash{V0: 2})): &account.UTXO{
+                               string(database.StandardUTXOKey(bc.Hash{V0: 2})): &account.UTXO{
                                        OutputID: bc.Hash{V0: 2},
                                },
-                               string(account.StandardUTXOKey(bc.Hash{V0: 2, V1: 2})): &account.UTXO{
+                               string(database.StandardUTXOKey(bc.Hash{V0: 2, V1: 2})): &account.UTXO{
                                        OutputID: bc.Hash{V0: 2, V1: 2},
                                },
                        },
@@ -123,10 +123,10 @@ func TestGetAccountUtxos(t *testing.T) {
                },
                {
                        dbUtxos: map[string]*account.UTXO{
-                               string(account.StandardUTXOKey(bc.Hash{V0: 3})): &account.UTXO{
+                               string(database.StandardUTXOKey(bc.Hash{V0: 3})): &account.UTXO{
                                        OutputID: bc.Hash{V0: 3},
                                },
-                               string(account.ContractUTXOKey(bc.Hash{V0: 4})): &account.UTXO{
+                               string(database.ContractUTXOKey(bc.Hash{V0: 4})): &account.UTXO{
                                        OutputID: bc.Hash{V0: 4},
                                },
                        },
@@ -155,10 +155,10 @@ func TestGetAccountUtxos(t *testing.T) {
                },
                {
                        dbUtxos: map[string]*account.UTXO{
-                               string(account.StandardUTXOKey(bc.Hash{V0: 3})): &account.UTXO{
+                               string(database.StandardUTXOKey(bc.Hash{V0: 3})): &account.UTXO{
                                        OutputID: bc.Hash{V0: 3},
                                },
-                               string(account.ContractUTXOKey(bc.Hash{V0: 4})): &account.UTXO{
+                               string(database.ContractUTXOKey(bc.Hash{V0: 4})): &account.UTXO{
                                        OutputID: bc.Hash{V0: 4},
                                },
                        },