log "github.com/sirupsen/logrus"
"github.com/vapor/account"
- "github.com/vapor/asset"
"github.com/vapor/blockchain/query"
"github.com/vapor/consensus"
"github.com/vapor/crypto/sha3pool"
- dbm "github.com/vapor/database/leveldb"
chainjson "github.com/vapor/encoding/json"
- "github.com/vapor/errors"
"github.com/vapor/protocol/bc"
"github.com/vapor/protocol/bc/types"
)
-const (
- //TxPrefix is wallet database transactions prefix
- TxPrefix = "TXS:"
- //TxIndexPrefix is wallet database tx index prefix
- TxIndexPrefix = "TID:"
- //TxIndexPrefix is wallet database global tx index prefix
- GlobalTxIndexPrefix = "GTID:"
-)
-
-var errAccntTxIDNotFound = errors.New("account TXID not found")
-
-func formatKey(blockHeight uint64, position uint32) string {
- return fmt.Sprintf("%016x%08x", blockHeight, position)
-}
-
-func calcAnnotatedKey(formatKey string) []byte {
- return []byte(TxPrefix + formatKey)
-}
-
-func calcDeleteKey(blockHeight uint64) []byte {
- return []byte(fmt.Sprintf("%s%016x", TxPrefix, blockHeight))
-}
-
-func calcTxIndexKey(txID string) []byte {
- return []byte(TxIndexPrefix + txID)
-}
-
-func calcGlobalTxIndexKey(txID string) []byte {
- return []byte(GlobalTxIndexPrefix + txID)
-}
-
-func calcGlobalTxIndex(blockHash *bc.Hash, position uint64) []byte {
- txIdx := make([]byte, 40)
- copy(txIdx[:32], blockHash.Bytes())
- binary.BigEndian.PutUint64(txIdx[32:], position)
- return txIdx
-}
-
func parseGlobalTxIdx(globalTxIdx []byte) (*bc.Hash, uint64) {
var hashBytes [32]byte
copy(hashBytes[:], globalTxIdx[:32])
return &hash, position
}
-// deleteTransaction delete transactions when orphan block rollback
-func (w *Wallet) deleteTransactions(batch dbm.Batch, height uint64) {
- tmpTx := query.AnnotatedTx{}
- txIter := w.DB.IteratorPrefix(calcDeleteKey(height))
- defer txIter.Release()
-
- for txIter.Next() {
- if err := json.Unmarshal(txIter.Value(), &tmpTx); err == nil {
- batch.Delete(calcTxIndexKey(tmpTx.ID.String()))
- }
- batch.Delete(txIter.Key())
- }
-}
-
// saveExternalAssetDefinition save external and local assets definition,
// when query ,query local first and if have no then query external
// details see getAliasDefinition
-func saveExternalAssetDefinition(b *types.Block, walletDB dbm.DB) {
- storeBatch := walletDB.NewBatch()
- defer storeBatch.Write()
+func saveExternalAssetDefinition(b *types.Block, store WalletStorer) error {
+ store.InitBatch()
+ defer store.CommitBatch()
for _, tx := range b.Transactions {
for _, orig := range tx.Inputs {
if cci, ok := orig.TypedInput.(*types.CrossChainInput); ok {
assetID := cci.AssetId
- if assetExist := walletDB.Get(asset.ExtAssetKey(assetID)); assetExist == nil {
- storeBatch.Set(asset.ExtAssetKey(assetID), cci.AssetDefinition)
+ assetExist, err := store.GetAssetDefinition(assetID)
+ if err != nil {
+ return err
+ }
+ if assetExist == nil {
+ store.SetAssetDefinition(assetID, cci.AssetDefinition)
}
}
}
}
+ return nil
}
// Summary is the struct of transaction's input and output summary
}
// indexTransactions saves all annotated transactions to the database.
-func (w *Wallet) indexTransactions(batch dbm.Batch, b *types.Block, txStatus *bc.TransactionStatus) error {
- annotatedTxs := w.filterAccountTxs(b, txStatus)
- saveExternalAssetDefinition(b, w.DB)
- annotateTxsAccount(annotatedTxs, w.DB)
-
+func (w *Wallet) indexTransactions(b *types.Block, txStatus *bc.TransactionStatus, annotatedTxs []*query.AnnotatedTx) error {
for _, tx := range annotatedTxs {
rawTx, err := json.Marshal(tx)
if err != nil {
return err
}
- batch.Set(calcAnnotatedKey(formatKey(b.Height, uint32(tx.Position))), rawTx)
- batch.Set(calcTxIndexKey(tx.ID.String()), []byte(formatKey(b.Height, uint32(tx.Position))))
-
- // delete unconfirmed transaction
- batch.Delete(calcUnconfirmedTxKey(tx.ID.String()))
+ w.store.SetTransaction(b.Height, tx.Position, tx.ID.String(), rawTx)
+ w.store.DeleteUnconfirmedTransaction(tx.ID.String())
}
if !w.TxIndexFlag {
for position, globalTx := range b.Transactions {
blockHash := b.BlockHeader.Hash()
- batch.Set(calcGlobalTxIndexKey(globalTx.ID.String()), calcGlobalTxIndex(&blockHash, uint64(position)))
+ w.store.SetGlobalTransactionIndex(globalTx.ID.String(), &blockHash, uint64(position))
}
return nil
var hash [32]byte
sha3pool.Sum256(hash[:], v.ControlProgram())
- if bytes := w.DB.Get(account.ContractKey(hash)); bytes != nil {
+ cp, err := w.store.GetControlProgram(hash)
+ if err != nil {
+ log.WithFields(log.Fields{"module": logModule, "err": err, "hash": string(hash[:])}).Error("filterAccountTxs fail.")
+ continue
+ }
+ if cp != nil {
annotatedTxs = append(annotatedTxs, w.buildAnnotatedTransaction(tx, b, statusFail, pos))
continue transactionLoop
}
if err != nil {
continue
}
- if bytes := w.DB.Get(account.StandardUTXOKey(outid)); bytes != nil {
+ if bytes := w.store.GetStandardUTXO(outid); bytes != nil {
annotatedTxs = append(annotatedTxs, w.buildAnnotatedTransaction(tx, b, statusFail, pos))
continue transactionLoop
}
func (w *Wallet) getAccountTxByTxID(txID string) (*query.AnnotatedTx, error) {
annotatedTx := &query.AnnotatedTx{}
- formatKey := w.DB.Get(calcTxIndexKey(txID))
- if formatKey == nil {
- return nil, errAccntTxIDNotFound
+ txInfo, err := w.store.GetTransaction(txID)
+ if err != nil {
+ return nil, err
}
- txInfo := w.DB.Get(calcAnnotatedKey(string(formatKey)))
if err := json.Unmarshal(txInfo, annotatedTx); err != nil {
return nil, err
}
}
func (w *Wallet) getGlobalTxByTxID(txID string) (*query.AnnotatedTx, error) {
- globalTxIdx := w.DB.Get(calcGlobalTxIndexKey(txID))
+ globalTxIdx := w.store.GetGlobalTransaction(txID)
if globalTxIdx == nil {
return nil, fmt.Errorf("No transaction(tx_id=%s) ", txID)
}
// GetTransactions get all walletDB transactions, and filter transactions by accountID optional
func (w *Wallet) GetTransactions(accountID string) ([]*query.AnnotatedTx, error) {
annotatedTxs := []*query.AnnotatedTx{}
+ annotatedTxs, err := w.store.GetTransactions()
+ if err != nil {
+ return nil, err
+ }
- txIter := w.DB.IteratorPrefix([]byte(TxPrefix))
- defer txIter.Release()
- for txIter.Next() {
- annotatedTx := &query.AnnotatedTx{}
- if err := json.Unmarshal(txIter.Value(), &annotatedTx); err != nil {
- return nil, err
- }
-
+ newAnnotatedTxs := []*query.AnnotatedTx{}
+ for _, annotatedTx := range annotatedTxs {
if accountID == "" || findTransactionsByAccount(annotatedTx, accountID) {
annotateTxsAsset(w, []*query.AnnotatedTx{annotatedTx})
- annotatedTxs = append([]*query.AnnotatedTx{annotatedTx}, annotatedTxs...)
+ newAnnotatedTxs = append([]*query.AnnotatedTx{annotatedTx}, newAnnotatedTxs...)
}
}
- return annotatedTxs, nil
+ return newAnnotatedTxs, nil
}
// GetAccountBalances return all account balances
type voteDetail struct {
Vote string `json:"vote"`
- VoteAmount uint64 `json:"vote_amount"`
+ VoteNumber uint64 `json:"vote_number"`
}
// AccountVotes account vote
type AccountVotes struct {
AccountID string `json:"account_id"`
Alias string `json:"account_alias"`
- TotalVoteAmount uint64 `json:"total_vote_amount"`
+ TotalVoteNumber uint64 `json:"total_vote_number"`
VoteDetails []voteDetail `json:"vote_details"`
}
for _, xpub := range sortedXpub {
voteDetails = append(voteDetails, voteDetail{
Vote: xpub,
- VoteAmount: accVote[id][xpub],
+ VoteNumber: accVote[id][xpub],
})
voteTotal += accVote[id][xpub]
}
Alias: alias,
AccountID: id,
VoteDetails: voteDetails,
- TotalVoteAmount: voteTotal,
+ TotalVoteNumber: voteTotal,
})
}