Merge pull request #1260 from obscuren/tx-drop-low-tx

core: drop low gas tx
This commit is contained in:
Jeffrey Wilcke
2015-06-15 09:09:44 -07:00
8 changed files with 60 additions and 24 deletions

View File

@ -5,7 +5,6 @@ import (
"fmt"
"io"
"math/big"
"os"
"runtime"
"sync"
"sync/atomic"
@ -235,15 +234,8 @@ func (bc *ChainManager) setLastState() {
if block != nil {
bc.currentBlock = block
bc.lastBlockHash = block.Hash()
} else { // TODO CLEAN THIS UP TMP CODE
block = bc.GetBlockByNumber(400000)
if block == nil {
fmt.Println("Fatal. LastBlock not found. Report this issue")
os.Exit(1)
}
bc.currentBlock = block
bc.lastBlockHash = block.Hash()
bc.insert(block)
} else {
glog.Fatalf("Fatal. LastBlock not found. Please run removedb and resync")
}
} else {
bc.Reset()

View File

@ -19,6 +19,7 @@ var (
// Transaction Pool Errors
ErrInvalidSender = errors.New("Invalid sender")
ErrNonce = errors.New("Nonce too low")
ErrCheap = errors.New("Gas price too low for acceptance")
ErrBalance = errors.New("Insufficient balance")
ErrNonExistentAccount = errors.New("Account does not exist or account balance too low")
ErrInsufficientFunds = errors.New("Insufficient funds for gas * price + value")
@ -27,6 +28,10 @@ var (
ErrNegativeValue = errors.New("Negative value")
)
const (
maxQueued = 200 // max limit of queued txs per address
)
type stateFn func() *state.StateDB
// TxPool contains all currently known transactions. Transactions
@ -41,6 +46,7 @@ type TxPool struct {
currentState stateFn // The state function which will allow us to do some pre checkes
pendingState *state.ManagedState
gasLimit func() *big.Int // The current gas limit function callback
minGasPrice *big.Int
eventMux *event.TypeMux
events event.Subscription
@ -57,8 +63,9 @@ func NewTxPool(eventMux *event.TypeMux, currentStateFn stateFn, gasLimitFn func(
eventMux: eventMux,
currentState: currentStateFn,
gasLimit: gasLimitFn,
minGasPrice: new(big.Int),
pendingState: state.ManageState(currentStateFn()),
events: eventMux.Subscribe(ChainEvent{}),
events: eventMux.Subscribe(ChainEvent{}, GasPriceChanged{}),
}
go pool.eventLoop()
@ -69,10 +76,15 @@ func (pool *TxPool) eventLoop() {
// Track chain events. When a chain events occurs (new chain canon block)
// we need to know the new state. The new state will help us determine
// the nonces in the managed state
for _ = range pool.events.Chan() {
for ev := range pool.events.Chan() {
pool.mu.Lock()
pool.resetState()
switch ev := ev.(type) {
case ChainEvent:
pool.resetState()
case GasPriceChanged:
pool.minGasPrice = ev.Price
}
pool.mu.Unlock()
}
@ -124,6 +136,11 @@ func (pool *TxPool) validateTx(tx *types.Transaction) error {
err error
)
// Drop transactions under our own minimal accepted gas price
if pool.minGasPrice.Cmp(tx.GasPrice()) > 0 {
return ErrCheap
}
// Validate the transaction sender and it's sig. Throw
// if the from fields is invalid.
if from, err = tx.From(); err != nil {
@ -335,7 +352,16 @@ func (pool *TxPool) checkQueue() {
// Find the next consecutive nonce range starting at the
// current account nonce.
sort.Sort(addq)
for _, e := range addq {
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.AccountNonce > guessedNonce {
break
}