OSDN Git Service

26b81cfc50370dd8c3b5b516779226554d5ce52b
[bytom/bytom.git] / wallet / unconfirmed.go
1 package wallet
2
3 import (
4         "encoding/json"
5
6         log "github.com/sirupsen/logrus"
7
8         "fmt"
9         "github.com/bytom/blockchain/query"
10         "github.com/bytom/protocol/bc/types"
11 )
12
13 const (
14         //unconfirmedTxPrefix is txpool unconfirmed transactions prefix
15         unconfirmedTxPrefix = "UTXS:"
16 )
17
18 func calcUnconfirmedKey(formatKey string) []byte {
19         return []byte(unconfirmedTxPrefix + formatKey)
20 }
21
22 // SaveUnconfirmedTx save unconfirmed annotated transaction to the database
23 func (w *Wallet) SaveUnconfirmedTx(tx *types.Tx) error {
24         annotatedTx := &query.AnnotatedTx{
25                 ID:      tx.ID,
26                 Inputs:  make([]*query.AnnotatedInput, 0, len(tx.Inputs)),
27                 Outputs: make([]*query.AnnotatedOutput, 0, len(tx.Outputs)),
28                 Size:    tx.SerializedSize,
29         }
30
31         for i := range tx.Inputs {
32                 annotatedTx.Inputs = append(annotatedTx.Inputs, w.BuildAnnotatedInput(tx, uint32(i)))
33         }
34         for i := range tx.Outputs {
35                 annotatedTx.Outputs = append(annotatedTx.Outputs, w.BuildAnnotatedOutput(tx, i))
36         }
37
38         // annotate account and asset
39         annotatedTxs := []*query.AnnotatedTx{}
40         annotatedTxs = append(annotatedTxs, annotatedTx)
41         annotateTxsAccount(annotatedTxs, w.DB)
42         annotateTxsAsset(w, annotatedTxs)
43
44         rawTx, err := json.Marshal(annotatedTxs[0])
45         if err != nil {
46                 log.WithField("err", err).Error("inserting unconfirmed annotated transaction to db")
47                 return err
48         }
49
50         w.DB.Set(calcUnconfirmedKey(tx.ID.String()), rawTx)
51         return nil
52 }
53
54 // DeleteUnconfirmedTxs delete unconfirmed annotated transaction from the database
55 func (w *Wallet) DeleteUnconfirmedTxs(txIDs []string) {
56         for _, txID := range txIDs {
57                 if exist := w.DB.Get(calcUnconfirmedKey(txID)); exist != nil {
58                         w.DB.Delete(calcUnconfirmedKey(txID))
59                 }
60         }
61 }
62
63 // RescanWalletTxPool rescan txPool
64 func (w *Wallet) RescanWalletTxPool() []string {
65         txIDs := []string{}
66
67         txPool := w.chain.GetTxPool()
68         txs := txPool.GetTransactions()
69         for _, txDesc := range txs {
70                 txIDs = append(txIDs, txDesc.Tx.ID.String())
71         }
72
73         return txIDs
74 }
75
76 // GetUnconfirmedTxByTxID get unconfirmed transaction by txID
77 func (w *Wallet) GetUnconfirmedTxByTxID(txID string) (*query.AnnotatedTx, error) {
78         formatKey := w.DB.Get(calcUnconfirmedKey(txID))
79         if formatKey == nil {
80                 return nil, fmt.Errorf("Not found unconfirmed transaction(tx_id=%s) ", txID)
81         }
82
83         annotatedTx := &query.AnnotatedTx{}
84         txInfo := w.DB.Get(calcAnnotatedKey(string(formatKey)))
85         if err := json.Unmarshal(txInfo, annotatedTx); err != nil {
86                 return nil, err
87         }
88
89         return annotatedTx, nil
90 }
91
92 // GetUnconfirmedTxsByAccountID get account unconfirmed txs by account ID
93 func (w *Wallet) GetUnconfirmedTxsByAccountID(accountID string) ([]*query.AnnotatedTx, error) {
94         annotatedTxs := []*query.AnnotatedTx{}
95
96         txIter := w.DB.IteratorPrefix([]byte(unconfirmedTxPrefix))
97         defer txIter.Release()
98         for txIter.Next() {
99                 annotatedTx := &query.AnnotatedTx{}
100                 if err := json.Unmarshal(txIter.Value(), &annotatedTx); err != nil {
101                         return nil, err
102                 }
103
104                 if accountID == "" {
105                         annotatedTxs = append(annotatedTxs, annotatedTx)
106                         continue
107                 }
108
109                 if findTransactionsByAccount(annotatedTx, accountID) {
110                         annotatedTxs = append(annotatedTxs, annotatedTx)
111                 }
112         }
113
114         return annotatedTxs, nil
115 }