core, miner: tx pool drops txs below ask price

This commit is contained in:
obscuren 2015-06-15 11:33:08 +02:00
parent 6f5c6150b7
commit 6d817e16c1
4 changed files with 23 additions and 6 deletions

View File

@ -19,6 +19,7 @@ var (
// Transaction Pool Errors // Transaction Pool Errors
ErrInvalidSender = errors.New("Invalid sender") ErrInvalidSender = errors.New("Invalid sender")
ErrNonce = errors.New("Nonce too low") ErrNonce = errors.New("Nonce too low")
ErrCheap = errors.New("Gas price too low for acceptance")
ErrBalance = errors.New("Insufficient balance") ErrBalance = errors.New("Insufficient balance")
ErrNonExistentAccount = errors.New("Account does not exist or account balance too low") ErrNonExistentAccount = errors.New("Account does not exist or account balance too low")
ErrInsufficientFunds = errors.New("Insufficient funds for gas * price + value") ErrInsufficientFunds = errors.New("Insufficient funds for gas * price + value")
@ -41,6 +42,7 @@ type TxPool struct {
currentState stateFn // The state function which will allow us to do some pre checkes currentState stateFn // The state function which will allow us to do some pre checkes
pendingState *state.ManagedState pendingState *state.ManagedState
gasLimit func() *big.Int // The current gas limit function callback gasLimit func() *big.Int // The current gas limit function callback
minGasPrice *big.Int
eventMux *event.TypeMux eventMux *event.TypeMux
events event.Subscription events event.Subscription
@ -57,8 +59,9 @@ func NewTxPool(eventMux *event.TypeMux, currentStateFn stateFn, gasLimitFn func(
eventMux: eventMux, eventMux: eventMux,
currentState: currentStateFn, currentState: currentStateFn,
gasLimit: gasLimitFn, gasLimit: gasLimitFn,
minGasPrice: new(big.Int),
pendingState: state.ManageState(currentStateFn()), pendingState: state.ManageState(currentStateFn()),
events: eventMux.Subscribe(ChainEvent{}), events: eventMux.Subscribe(ChainEvent{}, GasPriceChanged{}),
} }
go pool.eventLoop() go pool.eventLoop()
@ -69,10 +72,15 @@ func (pool *TxPool) eventLoop() {
// Track chain events. When a chain events occurs (new chain canon block) // 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 // we need to know the new state. The new state will help us determine
// the nonces in the managed state // the nonces in the managed state
for _ = range pool.events.Chan() { for ev := range pool.events.Chan() {
pool.mu.Lock() pool.mu.Lock()
pool.resetState() switch ev := ev.(type) {
case ChainEvent:
pool.resetState()
case GasPriceChanged:
pool.minGasPrice = ev.Price
}
pool.mu.Unlock() pool.mu.Unlock()
} }
@ -124,6 +132,11 @@ func (pool *TxPool) validateTx(tx *types.Transaction) error {
err 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 // Validate the transaction sender and it's sig. Throw
// if the from fields is invalid. // if the from fields is invalid.
if from, err = tx.From(); err != nil { if from, err = tx.From(); err != nil {

View File

@ -292,6 +292,7 @@ func New(config *Config) (*Ethereum, error) {
} }
eth.downloader = downloader.New(eth.EventMux(), eth.chainManager.HasBlock, eth.chainManager.GetBlock) eth.downloader = downloader.New(eth.EventMux(), eth.chainManager.HasBlock, eth.chainManager.GetBlock)
eth.txPool = core.NewTxPool(eth.EventMux(), eth.chainManager.State, eth.chainManager.GasLimit) eth.txPool = core.NewTxPool(eth.EventMux(), eth.chainManager.State, eth.chainManager.GasLimit)
eth.blockProcessor = core.NewBlockProcessor(stateDb, extraDb, eth.pow, eth.chainManager, eth.EventMux()) eth.blockProcessor = core.NewBlockProcessor(stateDb, extraDb, eth.pow, eth.chainManager, eth.EventMux())
eth.chainManager.SetProcessor(eth.blockProcessor) eth.chainManager.SetProcessor(eth.blockProcessor)
eth.miner = miner.New(eth, eth.EventMux(), eth.pow) eth.miner = miner.New(eth, eth.EventMux(), eth.pow)

View File

@ -77,7 +77,7 @@ func (m *Miner) SetGasPrice(price *big.Int) {
return return
} }
m.worker.gasPrice = price m.worker.setGasPrice(price)
} }
func (self *Miner) Start(coinbase common.Address, threads int) { func (self *Miner) Start(coinbase common.Address, threads int) {

View File

@ -6,6 +6,7 @@ import (
"sort" "sort"
"sync" "sync"
"sync/atomic" "sync/atomic"
"time"
"github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
@ -374,6 +375,8 @@ func (self *worker) commitNewWork() {
self.currentMu.Lock() self.currentMu.Lock()
defer self.currentMu.Unlock() defer self.currentMu.Unlock()
tstart := time.Now()
previous := self.current previous := self.current
self.makeCurrent() self.makeCurrent()
current := self.current current := self.current
@ -409,7 +412,7 @@ func (self *worker) commitNewWork() {
// We only care about logging if we're actually mining // We only care about logging if we're actually mining
if atomic.LoadInt32(&self.mining) == 1 { if atomic.LoadInt32(&self.mining) == 1 {
glog.V(logger.Info).Infof("commit new work on block %v with %d txs & %d uncles\n", current.block.Number(), current.tcount, len(uncles)) glog.V(logger.Info).Infof("commit new work on block %v with %d txs & %d uncles. Took %v\n", current.block.Number(), current.tcount, len(uncles), time.Since(tstart))
self.logLocalMinedBlocks(previous) self.logLocalMinedBlocks(previous)
} }
@ -437,7 +440,6 @@ func (self *worker) commitUncle(uncle *types.Header) error {
// Error not unique // Error not unique
return core.UncleError("Uncle not unique") return core.UncleError("Uncle not unique")
} }
self.current.uncles.Add(uncle.Hash())
if !self.current.ancestors.Has(uncle.ParentHash) { if !self.current.ancestors.Has(uncle.ParentHash) {
return core.UncleError(fmt.Sprintf("Uncle's parent unknown (%x)", uncle.ParentHash[0:4])) return core.UncleError(fmt.Sprintf("Uncle's parent unknown (%x)", uncle.ParentHash[0:4]))
@ -446,6 +448,7 @@ func (self *worker) commitUncle(uncle *types.Header) error {
if self.current.family.Has(uncle.Hash()) { if self.current.family.Has(uncle.Hash()) {
return core.UncleError(fmt.Sprintf("Uncle already in family (%x)", uncle.Hash())) return core.UncleError(fmt.Sprintf("Uncle already in family (%x)", uncle.Hash()))
} }
self.current.uncles.Add(uncle.Hash())
return nil return nil
} }