ErrDustTx = errors.New("transaction is dust tx")
)
+// DustFilterer is inerface for dust transaction filter rule
+type DustFilterer interface {
+ IsDust(tx *types.Tx) bool
+}
+
+// TxMsgEvent is message wrap for subscribe event
type TxMsgEvent struct{ TxMsg *TxPoolMsg }
// TxDesc store tx and related info for mining strategy
orphans map[bc.Hash]*orphanTx
orphansByPrev map[bc.Hash]map[bc.Hash]*orphanTx
errCache *lru.Cache
+ filters []DustFilterer
eventDispatcher *event.Dispatcher
}
// NewTxPool init a new TxPool
-func NewTxPool(store Store, dispatcher *event.Dispatcher) *TxPool {
+func NewTxPool(store Store, filters []DustFilterer, dispatcher *event.Dispatcher) *TxPool {
tp := &TxPool{
lastUpdated: time.Now().Unix(),
store: store,
orphans: make(map[bc.Hash]*orphanTx),
orphansByPrev: make(map[bc.Hash]map[bc.Hash]*orphanTx),
errCache: lru.New(maxCachedErrTxs),
+ filters: filters,
eventDispatcher: dispatcher,
}
go tp.orphanExpireWorker()
return false
}
+func isNoGasStatusFail(tx *types.Tx, statusFail bool) bool {
+ if !statusFail {
+ return false
+ }
+
+ for _, input := range tx.TxData.Inputs {
+ if *consensus.BTMAssetID == input.AssetID() {
+ return false
+ }
+ }
+ return true
+}
+
//IsDust checks if a tx has zero output
func (tp *TxPool) IsDust(tx *types.Tx) bool {
- return isTransactionZeroOutput(tx)
+ if ok := isTransactionZeroOutput(tx); ok {
+ return ok
+ }
+
+ for _, filter := range tp.filters {
+ if ok := filter.IsDust(tx); ok {
+ return ok
+ }
+ }
+ return false
}
func (tp *TxPool) processTransaction(tx *types.Tx, statusFail bool, height, fee uint64) (bool, error) {
log.WithFields(log.Fields{"module": logModule, "tx_id": tx.ID.String()}).Warn("dust tx")
return false, nil
}
+
+ if isNoGasStatusFail(tx, statusFail) {
+ log.WithFields(log.Fields{"module": logModule, "tx_id": tx.ID.String()}).Warn("drop no gas status fail tx")
+ return false, nil
+ }
return tp.processTransaction(tx, statusFail, height, fee)
}