const (
//UnconfirmedTxPrefix is txpool unconfirmed transactions prefix
- UnconfirmedTxPrefix = "UTXS:"
+ UnconfirmedTxPrefix = "UTXS:"
+ UnconfirmedTxCheckPeriod = 30 * time.Minute
+ MaxUnconfirmedTxDuration = 24 * time.Hour
)
func calcUnconfirmedTxKey(formatKey string) []byte {
func (a SortByTimestamp) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a SortByTimestamp) Less(i, j int) bool { return a[i].Timestamp > a[j].Timestamp }
+// SortByHeight implements sort.Interface for AnnotatedTx slices
+type SortByHeight []*query.AnnotatedTx
+
+func (a SortByHeight) Len() int { return len(a) }
+func (a SortByHeight) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
+func (a SortByHeight) Less(i, j int) bool { return a[i].BlockHeight > a[j].BlockHeight }
+
// AddUnconfirmedTx handle wallet status update when tx add into txpool
func (w *Wallet) AddUnconfirmedTx(txD *protocol.TxDesc) {
if err := w.saveUnconfirmedTx(txD.Tx); err != nil {
- log.WithField("err", err).Error("wallet fail on saveUnconfirmedTx")
+ log.WithFields(log.Fields{"module": logModule, "err": err}).Error("wallet fail on saveUnconfirmedTx")
}
utxos := txOutToUtxos(txD.Tx, txD.StatusFail, 0)
// RemoveUnconfirmedTx handle wallet status update when tx removed from txpool
func (w *Wallet) RemoveUnconfirmedTx(txD *protocol.TxDesc) {
+ if !w.checkRelatedTransaction(txD.Tx) {
+ return
+ }
+ w.DB.Delete(calcUnconfirmedTxKey(txD.Tx.ID.String()))
w.AccountMgr.RemoveUnconfirmedUtxo(txD.Tx.ResultIds)
}
w.DB.Set(calcUnconfirmedTxKey(tx.ID.String()), rawTx)
return nil
}
+
+func (w *Wallet) delExpiredTxs() error {
+ AnnotatedTx, err := w.GetUnconfirmedTxs("")
+ 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()))
+ }
+ }
+ return nil
+}
+
+//delUnconfirmedTx periodically delete locally stored timeout did not confirm txs
+func (w *Wallet) delUnconfirmedTx() {
+ if err := w.delExpiredTxs(); err != nil {
+ 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 {
+ log.WithFields(log.Fields{"module": logModule, "err": err}).Error("wallet fail on delUnconfirmedTx")
+ }
+ }
+}