MCPcopy Create free account
hub / github.com/CPChain/chain / add

Method add

core/tx_pool.go:720–797  ·  view source on GitHub ↗

add validates a transaction and inserts it into the non-executable queue for later pending promotion and execution. If the transaction is a replacement for an already pending or queued one, it overwrites the previous and returns this so outer code doesn't uselessly call promote. If a newly added tr

(tx *types.Transaction, local bool)

Source from the content-addressed store, hash-verified

718// whitelisted, preventing any associated transaction from being dropped out of
719// the pool due to pricing constraints.
720func (pool *TxPool) add(tx *types.Transaction, local bool) (bool, error) {
721 // If IsFifoTxQueue is true and the txpool is full, just ignore the tx.
722 if pool.config.IsFifoTxQueue && uint64(pool.all.Count()) >= pool.config.GlobalSlots+pool.config.GlobalQueue {
723 log.Debug("txpool is full")
724 return false, fmt.Errorf("txpool is full")
725 }
726
727 // If the transaction is already known, discard it
728 hash := tx.Hash()
729 if pool.all.Get(hash) != nil {
730 log.Debug("Discarding already known transaction", "hash", hash.Hex())
731 return false, fmt.Errorf("known transaction: %x", hash)
732 }
733 // If the transaction fails basic validation, discard it
734 if err := pool.validateTx(tx, local); err != nil {
735 log.Debug("Discarding invalid transaction", "hash", hash.Hex(), "err", err)
736 invalidTxCounter.Inc(1)
737 return false, err
738 }
739 // If the transaction pool is full, discard underpriced transactions
740 log.Debug("txPoolLen", "len", pool.all.Count())
741 if uint64(pool.all.Count()) >= pool.config.GlobalSlots+pool.config.GlobalQueue {
742 // If the new transaction is underpriced, don't accept it
743 if !local && pool.priced.Underpriced(tx, pool.locals) {
744 log.Debug("Discarding underpriced transaction", "hash", hash.Hex(), "price", tx.GasPrice())
745 underpricedTxCounter.Inc(1)
746 return false, ErrUnderpriced
747 }
748 // New transaction is better than our worse ones, make room for it
749 discardNumber := pool.all.Count() - int(pool.config.GlobalSlots+pool.config.GlobalQueue-1)
750 log.Debug("discardNumber", "discardNumber", discardNumber)
751 drop := pool.priced.Discard(discardNumber, pool.locals)
752 for _, tx := range drop {
753 log.Debug("Discarding freshly underpriced transaction", "hash", tx.Hash().Hex(), "price", tx.GasPrice())
754 underpricedTxCounter.Inc(1)
755 pool.removeTx(tx.Hash(), false)
756 }
757 }
758 // If the transaction is replacing an already pending one, do directly
759 from, _ := types.Sender(pool.signer, tx) // already validated
760 if list := pool.getPendingTxList(from); list != nil && list.Overlaps(tx) {
761 // Nonce already pending, check if required price bump is met
762 inserted, old := list.Add(tx, pool.config.PriceBump)
763 if !inserted {
764 pendingDiscardCounter.Inc(1)
765 return false, ErrReplaceUnderpriced
766 }
767 // New transaction is better, replace old one
768 if old != nil {
769 pool.all.Remove(old.Hash())
770 pool.priced.Removed()
771 pendingReplaceCounter.Inc(1)
772 }
773 pool.all.Add(tx)
774 pool.priced.Put(tx)
775 pool.journalTx(from, tx)
776
777 log.Debug("Pooled new executable transaction", "hash", hash.Hex(), "from", from, "to", tx.To())

Callers 6

addTxMethod · 0.95
addTxsLockedMethod · 0.95
TestTransactionChainForkFunction · 0.45
prestate_tracer.jsFile · 0.45

Calls 15

validateTxMethod · 0.95
removeTxMethod · 0.95
getPendingTxListMethod · 0.95
journalTxMethod · 0.95
enqueueTxMethod · 0.95
DebugMethod · 0.80
UnderpricedMethod · 0.80
OverlapsMethod · 0.80
RemovedMethod · 0.80
HashMethod · 0.65
GetMethod · 0.65
GasPriceMethod · 0.65

Tested by 3

TestTransactionChainForkFunction · 0.36