OSDN Git Service

cc68422b9dd62b0d75862bcd47c68dd381bec3e6
[bytom/bytom.git] / wallet / unconfirmed.go
1 package wallet
2
3 import (
4         "encoding/json"
5         "strings"
6
7         log "github.com/sirupsen/logrus"
8
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         log.Infof("insert unconfirmed tx=%s into db", tx.ID.String())
52         return nil
53 }
54
55 // DeleteUnconfirmedTxs delete unconfirmed annotated transactions from the database when these transactions are not existed in txpool
56 func (w *Wallet) DeleteUnconfirmedTxs(txIDs []string) error {
57         var TxIDsStr string
58         for i, txID := range txIDs {
59                 if i == 0 {
60                         TxIDsStr += txID
61                 }
62                 TxIDsStr = TxIDsStr + ":" + txID
63         }
64
65         txIter := w.DB.IteratorPrefix([]byte(unconfirmedTxPrefix))
66         defer txIter.Release()
67         for txIter.Next() {
68                 annotatedTx := &query.AnnotatedTx{}
69                 if err := json.Unmarshal(txIter.Value(), &annotatedTx); err != nil {
70                         return err
71                 }
72
73                 if !strings.Contains(TxIDsStr, annotatedTx.ID.String()) {
74                         w.DB.Delete(calcUnconfirmedKey(annotatedTx.ID.String()))
75                         log.Infof("delete unconfirmed tx=%s from db", annotatedTx.ID.String())
76                 }
77         }
78
79         return nil
80 }
81
82 // RescanWalletTxPool rescan txPool
83 func (w *Wallet) RescanWalletTxPool() []string {
84         txIDs := []string{}
85
86         txPool := w.chain.GetTxPool()
87         txs := txPool.GetTransactions()
88         for _, txDesc := range txs {
89                 txIDs = append(txIDs, txDesc.Tx.ID.String())
90         }
91
92         return txIDs
93 }
94
95 // GetUnconfirmedTxByTxID get unconfirmed transaction by txID
96 func (w *Wallet) GetUnconfirmedTxByTxID(txID string) (*query.AnnotatedTx, error) {
97         annotatedTx := &query.AnnotatedTx{}
98         txInfo := w.DB.Get(calcUnconfirmedKey(txID))
99         if err := json.Unmarshal(txInfo, annotatedTx); err != nil {
100                 return nil, err
101         }
102
103         return annotatedTx, nil
104 }
105
106 // GetUnconfirmedTxsByAccountID get account unconfirmed txs by account ID
107 func (w *Wallet) GetUnconfirmedTxsByAccountID(accountID string) ([]*query.AnnotatedTx, error) {
108         annotatedTxs := []*query.AnnotatedTx{}
109
110         txIter := w.DB.IteratorPrefix([]byte(unconfirmedTxPrefix))
111         defer txIter.Release()
112         for txIter.Next() {
113                 annotatedTx := &query.AnnotatedTx{}
114                 if err := json.Unmarshal(txIter.Value(), &annotatedTx); err != nil {
115                         return nil, err
116                 }
117
118                 if accountID == "" {
119                         annotatedTxs = append(annotatedTxs, annotatedTx)
120                         continue
121                 }
122
123                 if findTransactionsByAccount(annotatedTx, accountID) {
124                         annotatedTxs = append(annotatedTxs, annotatedTx)
125                 }
126         }
127
128         return annotatedTxs, nil
129 }