Golang implemented sidechain for Bytom
修订版 | 3a6cd9640bdb0eed33451a5af7a0e12cfe423165 (tree) |
---|---|
时间 | 2019-07-20 11:58:14 |
作者 | apolloww <32606824+apolloww@user...> |
Commiter | Paladz |
txpool: periodically sweep pool for stale Txs (#337)
@@ -32,6 +32,9 @@ var ( | ||
32 | 32 | orphanTTL = 60 * time.Second |
33 | 33 | orphanExpireScanInterval = 30 * time.Second |
34 | 34 | |
35 | + txTTL = 1 * time.Hour | |
36 | + txExpireScanInterval = 20 * time.Minute | |
37 | + | |
35 | 38 | // ErrTransactionNotExist is the pre-defined error message |
36 | 39 | ErrTransactionNotExist = errors.New("transaction are not existed in the mempool") |
37 | 40 | // ErrPoolIsFull indicates the pool is full |
@@ -89,6 +92,7 @@ func NewTxPool(store Store, dispatcher *event.Dispatcher) *TxPool { | ||
89 | 92 | eventDispatcher: dispatcher, |
90 | 93 | } |
91 | 94 | go tp.orphanExpireWorker() |
95 | + go tp.txExpireWorker() | |
92 | 96 | return tp |
93 | 97 | } |
94 | 98 |
@@ -100,8 +104,8 @@ func (tp *TxPool) AddErrCache(txHash *bc.Hash, err error) { | ||
100 | 104 | tp.errCache.Add(txHash, err) |
101 | 105 | } |
102 | 106 | |
103 | -// ExpireOrphan expire all the orphans that before the input time range | |
104 | -func (tp *TxPool) ExpireOrphan(now time.Time) { | |
107 | +// expireOrphan expire all the orphans that before the input time range | |
108 | +func (tp *TxPool) expireOrphan(now time.Time) { | |
105 | 109 | tp.mtx.Lock() |
106 | 110 | defer tp.mtx.Unlock() |
107 | 111 |
@@ -129,19 +133,24 @@ func (tp *TxPool) RemoveTransaction(txHash *bc.Hash) { | ||
129 | 133 | tp.mtx.Lock() |
130 | 134 | defer tp.mtx.Unlock() |
131 | 135 | |
136 | + if txD := tp.removeTransaction(txHash); txD != nil { | |
137 | + atomic.StoreInt64(&tp.lastUpdated, time.Now().Unix()) | |
138 | + tp.eventDispatcher.Post(TxMsgEvent{TxMsg: &TxPoolMsg{TxDesc: txD, MsgType: MsgRemoveTx}}) | |
139 | + log.WithFields(log.Fields{"module": logModule, "tx_id": txHash}).Debug("remove tx from mempool") | |
140 | + } | |
141 | +} | |
142 | + | |
143 | +func (tp *TxPool) removeTransaction(txHash *bc.Hash) *TxDesc { | |
132 | 144 | txD, ok := tp.pool[*txHash] |
133 | 145 | if !ok { |
134 | - return | |
146 | + return nil | |
135 | 147 | } |
136 | 148 | |
137 | 149 | for _, output := range txD.Tx.ResultIds { |
138 | 150 | delete(tp.utxo, *output) |
139 | 151 | } |
140 | 152 | delete(tp.pool, *txHash) |
141 | - | |
142 | - atomic.StoreInt64(&tp.lastUpdated, time.Now().Unix()) | |
143 | - tp.eventDispatcher.Post(TxMsgEvent{TxMsg: &TxPoolMsg{TxDesc: txD, MsgType: MsgRemoveTx}}) | |
144 | - log.WithFields(log.Fields{"module": logModule, "tx_id": txHash}).Debug("remove tx from mempool") | |
153 | + return txD | |
145 | 154 | } |
146 | 155 | |
147 | 156 | // GetTransaction return the TxDesc by hash |
@@ -201,6 +210,7 @@ func isTransactionZeroOutput(tx *types.Tx) bool { | ||
201 | 210 | return false |
202 | 211 | } |
203 | 212 | |
213 | +//IsDust checks if a tx has zero output | |
204 | 214 | func (tp *TxPool) IsDust(tx *types.Tx) bool { |
205 | 215 | return isTransactionZeroOutput(tx) |
206 | 216 | } |
@@ -313,7 +323,7 @@ func (tp *TxPool) orphanExpireWorker() { | ||
313 | 323 | defer ticker.Stop() |
314 | 324 | |
315 | 325 | for now := range ticker.C { |
316 | - tp.ExpireOrphan(now) | |
326 | + tp.expireOrphan(now) | |
317 | 327 | } |
318 | 328 | } |
319 | 329 |
@@ -368,3 +378,25 @@ func (tp *TxPool) removeOrphan(hash *bc.Hash) { | ||
368 | 378 | } |
369 | 379 | delete(tp.orphans, *hash) |
370 | 380 | } |
381 | + | |
382 | +func (tp *TxPool) txExpireWorker() { | |
383 | + ticker := time.NewTicker(txExpireScanInterval) | |
384 | + defer ticker.Stop() | |
385 | + | |
386 | + for now := range ticker.C { | |
387 | + tp.expireTx(now) | |
388 | + } | |
389 | +} | |
390 | + | |
391 | +// expireTx expires all the Txs that before the input time range | |
392 | +func (tp *TxPool) expireTx(now time.Time) { | |
393 | + tp.mtx.Lock() | |
394 | + defer tp.mtx.Unlock() | |
395 | + | |
396 | + cutOff := now.Add(-txTTL) | |
397 | + for hash, txD := range tp.pool { | |
398 | + if txD.Added.Before(cutOff) { | |
399 | + tp.removeTransaction(&hash) | |
400 | + } | |
401 | + } | |
402 | +} |
@@ -422,7 +422,7 @@ func TestExpireOrphan(t *testing.T) { | ||
422 | 422 | }, |
423 | 423 | } |
424 | 424 | |
425 | - before.ExpireOrphan(time.Unix(1633479701, 0)) | |
425 | + before.expireOrphan(time.Unix(1633479701, 0)) | |
426 | 426 | if !testutil.DeepEqual(before, want) { |
427 | 427 | t.Errorf("got %v want %v", before, want) |
428 | 428 | } |