// Manager stores accounts and their associated control programs.
type Manager struct {
- db dbm.DB
+ store database.AccountStorer
chain *protocol.Chain
utxoKeeper *utxoKeeper
}
// 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),
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
}
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
}
}
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)
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)
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
}
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
}
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
}
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
}
return m.FindByID(cachedID.(string))
}
- rawID := m.db.Get(database.AccountAliasKey(alias))
+ rawID := m.store.GetAccountByAccountAlias(alias)
if rawID == nil {
return nil, ErrFindAccount
}
return cachedAccount.(*Account), nil
}
- rawAccount := m.db.Get(database.AccountIDKey(id))
+ rawAccount := m.store.GetAccountByAccountID(id)
if rawAccount == nil {
return nil, ErrFindAccount
}
// 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
}
// 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 ""
}
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{}
// 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
}
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
// 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
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
}
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 {
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
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
}
t.Fatal(err)
}
- m.db.Set(StandardUTXOKey(utxo.OutputID), data)
+ m.store.SetStandardUTXO(utxo.OutputID, data)
}
cases := []struct {
"encoding/json"
log "github.com/sirupsen/logrus"
- "github.com/vapor/database"
)
// ImageSlice record info of single account
}
// 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
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,
}).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
}
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
}
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{
log "github.com/sirupsen/logrus"
- dbm "github.com/vapor/database/leveldb"
+ "github.com/vapor/database"
"github.com/vapor/errors"
"github.com/vapor/protocol/bc"
)
// `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
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),
}
}
- 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
}
}
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
"testing"
"time"
+ "github.com/vapor/database"
+
dbm "github.com/vapor/database/leveldb"
"github.com/vapor/protocol/bc"
"github.com/vapor/testutil"
}{
{
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{},
},
{
before: utxoKeeper{
- db: testDB,
+ store: database.NewAccountStore(testDB),
currentHeight: currentHeight,
unconfirmed: map[bc.Hash]*UTXO{
bc.NewHash([32]byte{0x01}): &UTXO{
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{
},
{
before: utxoKeeper{
- db: testDB,
+ store: database.NewAccountStore(testDB),
currentHeight: currentHeight,
unconfirmed: map[bc.Hash]*UTXO{
bc.NewHash([32]byte{0x01}): &UTXO{
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{
},
{
before: utxoKeeper{
- db: testDB,
+ store: database.NewAccountStore(testDB),
currentHeight: currentHeight,
unconfirmed: map[bc.Hash]*UTXO{
bc.NewHash([32]byte{0x01}): &UTXO{
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{
},
{
before: utxoKeeper{
- db: testDB,
+ store: database.NewAccountStore(testDB),
currentHeight: currentHeight,
unconfirmed: map[bc.Hash]*UTXO{
bc.NewHash([32]byte{0x01}): &UTXO{
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{
},
{
before: utxoKeeper{
- db: testDB,
+ store: database.NewAccountStore(testDB),
currentHeight: currentHeight,
nextIndex: 1,
unconfirmed: map[bc.Hash]*UTXO{
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{
},
{
before: utxoKeeper{
- db: testDB,
+ store: database.NewAccountStore(testDB),
currentHeight: currentHeight,
unconfirmed: map[bc.Hash]*UTXO{
bc.NewHash([32]byte{0x01}): &UTXO{
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{
}{
{
before: utxoKeeper{
- db: testDB,
+ store: database.NewAccountStore(testDB),
currentHeight: currentHeight,
unconfirmed: map[bc.Hash]*UTXO{
bc.NewHash([32]byte{0x01}): &UTXO{
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{
},
{
before: utxoKeeper{
- db: testDB,
+ store: database.NewAccountStore(testDB),
currentHeight: currentHeight,
unconfirmed: map[bc.Hash]*UTXO{
bc.NewHash([32]byte{0x01}): &UTXO{
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{
},
{
before: utxoKeeper{
- db: testDB,
+ store: database.NewAccountStore(testDB),
currentHeight: currentHeight,
unconfirmed: map[bc.Hash]*UTXO{
bc.NewHash([32]byte{0x01}): &UTXO{
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{
}{
{
uk: utxoKeeper{
- db: testDB,
+ store: database.NewAccountStore(testDB),
currentHeight: currentHeight,
unconfirmed: map[bc.Hash]*UTXO{},
},
},
{
uk: utxoKeeper{
- db: testDB,
+ store: database.NewAccountStore(testDB),
currentHeight: currentHeight,
unconfirmed: map[bc.Hash]*UTXO{},
},
},
{
uk: utxoKeeper{
- db: testDB,
+ store: database.NewAccountStore(testDB),
currentHeight: currentHeight,
unconfirmed: map[bc.Hash]*UTXO{},
},
},
{
uk: utxoKeeper{
- db: testDB,
+ store: database.NewAccountStore(testDB),
currentHeight: currentHeight,
unconfirmed: map[bc.Hash]*UTXO{
bc.NewHash([32]byte{0x01}): &UTXO{
},
{
uk: utxoKeeper{
- db: testDB,
+ store: database.NewAccountStore(testDB),
currentHeight: currentHeight,
unconfirmed: map[bc.Hash]*UTXO{
bc.NewHash([32]byte{0x11}): &UTXO{
},
{
uk: utxoKeeper{
- db: testDB,
+ store: database.NewAccountStore(testDB),
currentHeight: currentHeight,
unconfirmed: map[bc.Hash]*UTXO{
bc.NewHash([32]byte{0x01}): &UTXO{
},
{
uk: utxoKeeper{
- db: testDB,
+ store: database.NewAccountStore(testDB),
currentHeight: currentHeight,
unconfirmed: map[bc.Hash]*UTXO{},
},
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)
}
for _, u := range c.dbUtxos {
- testDB.Delete(StandardUTXOKey(u.OutputID))
+ testDB.Delete(database.StandardUTXOKey(u.OutputID))
}
}
}
}{
{
uk: utxoKeeper{
- db: testDB,
+ store: database.NewAccountStore(testDB),
currentHeight: currentHeight,
unconfirmed: map[bc.Hash]*UTXO{},
},
},
{
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})},
},
{
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})},
},
{
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})},
},
{
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})},
}
for _, u := range c.dbUtxos {
- testDB.Delete(StandardUTXOKey(u.OutputID))
+ testDB.Delete(database.StandardUTXOKey(u.OutputID))
}
}
}
// 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)
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.
}
}
+// 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
// 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
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 {
// 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
func (store *AccountStore) GetFirstAccount() ([]byte, error) {
accountIter := store.accountDB.IteratorPrefix([]byte(AccountPrefix))
defer accountIter.Release()
+
if !accountIter.Next() {
return nil, ErrFindAccount
}
// 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
}
// 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())
}
// 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())
}
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)
+ }
+}
"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"
// 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{}
},
{
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},
},
},
},
{
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},
},
},
},
{
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},
},
},
},
{
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},
},
},
},
{
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},
},
},