OSDN Git Service

Wallet store interface (#217)
[bytom/vapor.git] / wallet / unconfirmed.go
index 843c289..8effda0 100644 (file)
@@ -1,14 +1,14 @@
 package wallet
 
 import (
-       "encoding/json"
        "fmt"
        "sort"
        "time"
 
+       "github.com/vapor/protocol/bc"
+
        log "github.com/sirupsen/logrus"
 
-       "github.com/vapor/account"
        "github.com/vapor/blockchain/query"
        "github.com/vapor/crypto/sha3pool"
        "github.com/vapor/protocol"
@@ -16,16 +16,10 @@ import (
 )
 
 const (
-       //UnconfirmedTxPrefix is txpool unconfirmed transactions prefix
-       UnconfirmedTxPrefix      = "UTXS:"
        UnconfirmedTxCheckPeriod = 30 * time.Minute
        MaxUnconfirmedTxDuration = 24 * time.Hour
 )
 
-func calcUnconfirmedTxKey(formatKey string) []byte {
-       return []byte(UnconfirmedTxPrefix + formatKey)
-}
-
 // SortByTimestamp implements sort.Interface for AnnotatedTx slices
 type SortByTimestamp []*query.AnnotatedTx
 
@@ -54,37 +48,33 @@ func (w *Wallet) AddUnconfirmedTx(txD *protocol.TxDesc) {
 // GetUnconfirmedTxs get account unconfirmed transactions, filter transactions by accountID when accountID is not empty
 func (w *Wallet) GetUnconfirmedTxs(accountID string) ([]*query.AnnotatedTx, error) {
        annotatedTxs := []*query.AnnotatedTx{}
-       txIter := w.DB.IteratorPrefix([]byte(UnconfirmedTxPrefix))
-       defer txIter.Release()
-
-       for txIter.Next() {
-               annotatedTx := &query.AnnotatedTx{}
-               if err := json.Unmarshal(txIter.Value(), &annotatedTx); err != nil {
-                       return nil, err
-               }
+       annotatedTxs, err := w.Store.ListUnconfirmedTransactions()
+       if 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...)
                }
        }
 
-       sort.Sort(SortByTimestamp(annotatedTxs))
-       return annotatedTxs, nil
+       sort.Sort(SortByTimestamp(newAnnotatedTxs))
+       return newAnnotatedTxs, nil
 }
 
 // GetUnconfirmedTxByTxID get unconfirmed transaction by txID
 func (w *Wallet) GetUnconfirmedTxByTxID(txID string) (*query.AnnotatedTx, error) {
-       annotatedTx := &query.AnnotatedTx{}
-       txInfo := w.DB.Get(calcUnconfirmedTxKey(txID))
-       if txInfo == nil {
-               return nil, fmt.Errorf("No transaction(tx_id=%s) from txpool", txID)
-       }
-
-       if err := json.Unmarshal(txInfo, annotatedTx); err != nil {
+       annotatedTx, err := w.Store.GetUnconfirmedTransaction(txID)
+       if err != nil {
                return nil, err
        }
 
+       if annotatedTx == nil {
+               return nil, fmt.Errorf("No transaction(tx_id=%s) from txpool", txID)
+       }
        annotateTxsAsset(w, []*query.AnnotatedTx{annotatedTx})
        return annotatedTx, nil
 }
@@ -94,7 +84,8 @@ func (w *Wallet) RemoveUnconfirmedTx(txD *protocol.TxDesc) {
        if !w.checkRelatedTransaction(txD.Tx) {
                return
        }
-       w.DB.Delete(calcUnconfirmedTxKey(txD.Tx.ID.String()))
+
+       w.Store.DeleteUnconfirmedTransaction(txD.Tx.ID.String())
        w.AccountMgr.RemoveUnconfirmedUtxo(txD.Tx.ResultIds)
 }
 
@@ -121,7 +112,12 @@ func (w *Wallet) checkRelatedTransaction(tx *types.Tx) bool {
        for _, v := range tx.Outputs {
                var hash [32]byte
                sha3pool.Sum256(hash[:], v.ControlProgram())
-               if bytes := w.DB.Get(account.ContractKey(hash)); bytes != nil {
+               cp, err := w.AccountMgr.GetControlProgram(bc.NewHash(hash))
+               if err != nil {
+                       log.WithFields(log.Fields{"module": logModule, "err": err, "hash": string(hash[:])}).Error("checkRelatedTransaction fail.")
+                       continue
+               }
+               if cp != nil {
                        return true
                }
        }
@@ -131,7 +127,12 @@ func (w *Wallet) checkRelatedTransaction(tx *types.Tx) bool {
                if err != nil {
                        continue
                }
-               if bytes := w.DB.Get(account.StandardUTXOKey(outid)); bytes != nil {
+               utxo, err := w.Store.GetStandardUTXO(outid)
+               if err != nil {
+                       log.WithFields(log.Fields{"module": logModule, "err": err, "outputID": outid.String()}).Error("checkRelatedTransaction fail.")
+                       continue
+               }
+               if utxo != nil {
                        return true
                }
        }
@@ -148,14 +149,11 @@ func (w *Wallet) saveUnconfirmedTx(tx *types.Tx) error {
        annotatedTx := w.buildAnnotatedUnconfirmedTx(tx)
        annotatedTxs := []*query.AnnotatedTx{}
        annotatedTxs = append(annotatedTxs, annotatedTx)
-       annotateTxsAccount(annotatedTxs, w.DB)
+       w.annotateTxsAccount(annotatedTxs)
 
-       rawTx, err := json.Marshal(annotatedTxs[0])
-       if err != nil {
+       if err := w.Store.SetUnconfirmedTransaction(tx.ID.String(), annotatedTxs[0]); err != nil {
                return err
        }
-
-       w.DB.Set(calcUnconfirmedTxKey(tx.ID.String()), rawTx)
        return nil
 }
 
@@ -164,9 +162,10 @@ func (w *Wallet) delExpiredTxs() error {
        if err != nil {
                return err
        }
+
        for _, tx := range AnnotatedTx {
                if time.Now().After(time.Unix(int64(tx.Timestamp), 0).Add(MaxUnconfirmedTxDuration)) {
-                       w.DB.Delete(calcUnconfirmedTxKey(tx.ID.String()))
+                       w.Store.DeleteUnconfirmedTransaction(tx.ID.String())
                }
        }
        return nil
@@ -178,8 +177,10 @@ func (w *Wallet) delUnconfirmedTx() {
                log.WithFields(log.Fields{"module": logModule, "err": err}).Error("wallet fail on delUnconfirmedTx")
                return
        }
+
        ticker := time.NewTicker(UnconfirmedTxCheckPeriod)
        defer ticker.Stop()
+
        for {
                <-ticker.C
                if err := w.delExpiredTxs(); err != nil {