|
|
@@ -29,7 +29,7 @@ var (
|
|
|
)
|
|
|
|
|
|
const (
|
|
|
- maxQueued = 200 // max limit of queued txs per address
|
|
|
+ maxQueued = 64 // max limit of queued txs per address
|
|
|
)
|
|
|
|
|
|
type stateFn func() *state.StateDB
|
|
|
@@ -129,6 +129,17 @@ func (pool *TxPool) State() *state.ManagedState {
|
|
|
return pool.pendingState
|
|
|
}
|
|
|
|
|
|
+func (pool *TxPool) Stats() (pending int, queued int) {
|
|
|
+ pool.mu.RLock()
|
|
|
+ defer pool.mu.RUnlock()
|
|
|
+
|
|
|
+ pending = len(pool.pending)
|
|
|
+ for _, txs := range pool.queue {
|
|
|
+ queued += len(txs)
|
|
|
+ }
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
// validateTx checks whether a transaction is valid according
|
|
|
// to the consensus rules.
|
|
|
func (pool *TxPool) validateTx(tx *types.Transaction) error {
|
|
|
@@ -214,9 +225,6 @@ func (self *TxPool) add(tx *types.Transaction) error {
|
|
|
glog.Infof("(t) %x => %s (%v) %x\n", from, toname, tx.Value, hash)
|
|
|
}
|
|
|
|
|
|
- // check and validate the queueue
|
|
|
- self.checkQueue()
|
|
|
-
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
@@ -245,11 +253,17 @@ func (pool *TxPool) addTx(hash common.Hash, addr common.Address, tx *types.Trans
|
|
|
}
|
|
|
|
|
|
// Add queues a single transaction in the pool if it is valid.
|
|
|
-func (self *TxPool) Add(tx *types.Transaction) error {
|
|
|
+func (self *TxPool) Add(tx *types.Transaction) (err error) {
|
|
|
self.mu.Lock()
|
|
|
defer self.mu.Unlock()
|
|
|
|
|
|
- return self.add(tx)
|
|
|
+ err = self.add(tx)
|
|
|
+ if err == nil {
|
|
|
+ // check and validate the queueue
|
|
|
+ self.checkQueue()
|
|
|
+ }
|
|
|
+
|
|
|
+ return
|
|
|
}
|
|
|
|
|
|
// AddTransactions attempts to queue all valid transactions in txs.
|
|
|
@@ -265,6 +279,9 @@ func (self *TxPool) AddTransactions(txs []*types.Transaction) {
|
|
|
glog.V(logger.Debug).Infof("tx %x\n", h[:4])
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ // check and validate the queueue
|
|
|
+ self.checkQueue()
|
|
|
}
|
|
|
|
|
|
// GetTransaction returns a transaction if it is contained in the pool
|
|
|
@@ -327,6 +344,23 @@ func (self *TxPool) RemoveTransactions(txs types.Transactions) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+func (pool *TxPool) removeTx(hash common.Hash) {
|
|
|
+ // delete from pending pool
|
|
|
+ delete(pool.pending, hash)
|
|
|
+ // delete from queue
|
|
|
+ for address, txs := range pool.queue {
|
|
|
+ if _, ok := txs[hash]; ok {
|
|
|
+ if len(txs) == 1 {
|
|
|
+ // if only one tx, remove entire address entry.
|
|
|
+ delete(pool.queue, address)
|
|
|
+ } else {
|
|
|
+ delete(txs, hash)
|
|
|
+ }
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
// checkQueue moves transactions that have become processable to main pool.
|
|
|
func (pool *TxPool) checkQueue() {
|
|
|
state := pool.pendingState
|
|
|
@@ -354,13 +388,19 @@ func (pool *TxPool) checkQueue() {
|
|
|
for i, e := range addq {
|
|
|
// start deleting the transactions from the queue if they exceed the limit
|
|
|
if i > maxQueued {
|
|
|
- if glog.V(logger.Debug) {
|
|
|
- glog.Infof("Queued tx limit exceeded for %s. Tx %s removed\n", common.PP(address[:]), common.PP(e.hash[:]))
|
|
|
- }
|
|
|
delete(pool.queue[address], e.hash)
|
|
|
continue
|
|
|
}
|
|
|
+
|
|
|
if e.Nonce() > guessedNonce {
|
|
|
+ if len(addq)-i > maxQueued {
|
|
|
+ if glog.V(logger.Debug) {
|
|
|
+ glog.Infof("Queued tx limit exceeded for %s. Tx %s removed\n", common.PP(address[:]), common.PP(e.hash[:]))
|
|
|
+ }
|
|
|
+ for j := i + maxQueued; j < len(addq); j++ {
|
|
|
+ delete(txs, addq[j].hash)
|
|
|
+ }
|
|
|
+ }
|
|
|
break
|
|
|
}
|
|
|
delete(txs, e.hash)
|
|
|
@@ -373,23 +413,6 @@ func (pool *TxPool) checkQueue() {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-func (pool *TxPool) removeTx(hash common.Hash) {
|
|
|
- // delete from pending pool
|
|
|
- delete(pool.pending, hash)
|
|
|
- // delete from queue
|
|
|
- for address, txs := range pool.queue {
|
|
|
- if _, ok := txs[hash]; ok {
|
|
|
- if len(txs) == 1 {
|
|
|
- // if only one tx, remove entire address entry.
|
|
|
- delete(pool.queue, address)
|
|
|
- } else {
|
|
|
- delete(txs, hash)
|
|
|
- }
|
|
|
- break
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
// validatePool removes invalid and processed transactions from the main pool.
|
|
|
func (pool *TxPool) validatePool() {
|
|
|
state := pool.currentState()
|