OSDN Git Service

Merge pull request #41 from Bytom/dev
[bytom/vapor.git] / protocol / txpool.go
index e6f175a..cd7ebf1 100644 (file)
@@ -66,6 +66,7 @@ type TxPool struct {
        utxo          map[bc.Hash]*types.Tx
        orphans       map[bc.Hash]*orphanTx
        orphansByPrev map[bc.Hash]map[bc.Hash]*orphanTx
+       claimTx       map[bc.Hash]bool
        errCache      *lru.Cache
        msgCh         chan *TxPoolMsg
 }
@@ -79,6 +80,7 @@ func NewTxPool(store Store) *TxPool {
                utxo:          make(map[bc.Hash]*types.Tx),
                orphans:       make(map[bc.Hash]*orphanTx),
                orphansByPrev: make(map[bc.Hash]map[bc.Hash]*orphanTx),
+               claimTx:       make(map[bc.Hash]bool),
                errCache:      lru.New(maxCachedErrTxs),
                msgCh:         make(chan *TxPoolMsg, maxMsgChSize),
        }
@@ -136,6 +138,7 @@ func (tp *TxPool) RemoveTransaction(txHash *bc.Hash) {
        for _, output := range txD.Tx.ResultIds {
                delete(tp.utxo, *output)
        }
+       tp.removeClaimTx(txD.Tx)
        delete(tp.pool, *txHash)
 
        atomic.StoreInt64(&tp.lastUpdated, time.Now().Unix())
@@ -196,11 +199,10 @@ func (tp *TxPool) ProcessTransaction(tx *types.Tx, statusFail bool, height, fee
        tp.mtx.Lock()
        defer tp.mtx.Unlock()
 
-       if tp.isWithdrawSpent(tx) {
+       if tp.IsWithdrawSpent(tx) {
                log.WithFields(log.Fields{"module": "ProcessTransaction", "error": "pegin-already-claimed"}).Error("ProcessTransaction error")
                return false, errors.New("pegin-already-claimed")
        }
-
        txD := &TxDesc{
                Tx:         tx,
                StatusFail: statusFail,
@@ -224,11 +226,12 @@ func (tp *TxPool) ProcessTransaction(tx *types.Tx, statusFail bool, height, fee
        return false, nil
 }
 
-func (tp *TxPool) isWithdrawSpent(tx *types.Tx) bool {
+func (tp *TxPool) IsWithdrawSpent(tx *types.Tx) bool {
        for key, value := range tx.Entries {
                switch value.(type) {
                case *bc.Claim:
-                       return tp.store.IsWithdrawSpent(&key)
+                       _, ok := tp.claimTx[key]
+                       return tp.store.IsWithdrawSpent(&key) || ok
                default:
                        continue
                }
@@ -237,6 +240,28 @@ func (tp *TxPool) isWithdrawSpent(tx *types.Tx) bool {
        return false
 }
 
+func (tp *TxPool) addClaimTx(tx *types.Tx) {
+       for key, value := range tx.Entries {
+               switch value.(type) {
+               case *bc.Claim:
+                       tp.claimTx[key] = true
+               default:
+                       continue
+               }
+       }
+}
+
+func (tp *TxPool) removeClaimTx(tx *types.Tx) {
+       for key, value := range tx.Entries {
+               switch value.(type) {
+               case *bc.Claim:
+                       delete(tp.claimTx, key)
+               default:
+                       continue
+               }
+       }
+}
+
 func (tp *TxPool) addOrphan(txD *TxDesc, requireParents []*bc.Hash) error {
        if len(tp.orphans) >= maxOrphanNum {
                return ErrPoolIsFull
@@ -261,6 +286,8 @@ func (tp *TxPool) addTransaction(txD *TxDesc) error {
        tx := txD.Tx
        txD.Added = time.Now()
        tp.pool[tx.ID] = txD
+       // 增加一个claim id 到到claim pool中
+       tp.addClaimTx(tx)
        for _, id := range tx.ResultIds {
                output, err := tx.Output(*id)
                if err != nil {
@@ -274,6 +301,7 @@ func (tp *TxPool) addTransaction(txD *TxDesc) error {
 
        atomic.StoreInt64(&tp.lastUpdated, time.Now().Unix())
        tp.msgCh <- &TxPoolMsg{TxDesc: txD, MsgType: MsgNewTx}
+
        log.WithField("tx_id", tx.ID.String()).Debug("Add tx to mempool")
        return nil
 }