diff --git a/cmd/geth/admin.go b/cmd/geth/admin.go index 49e2dc6f8b..2b99566386 100644 --- a/cmd/geth/admin.go +++ b/cmd/geth/admin.go @@ -70,6 +70,7 @@ func (js *jsre) adminBindings() { miner.Set("stop", js.stopMining) miner.Set("hashrate", js.hashrate) miner.Set("setExtra", js.setExtra) + miner.Set("setGasPrice", js.setGasPrice) admin.Set("debug", struct{}{}) t, _ = admin.Get("debug") @@ -236,6 +237,17 @@ func (js *jsre) setExtra(call otto.FunctionCall) otto.Value { return otto.UndefinedValue() } +func (js *jsre) setGasPrice(call otto.FunctionCall) otto.Value { + gasPrice, err := call.Argument(0).ToString() + if err != nil { + fmt.Println(err) + return otto.UndefinedValue() + } + + js.ethereum.Miner().SetGasPrice(common.String2Big(gasPrice)) + return otto.UndefinedValue() +} + func (js *jsre) hashrate(otto.FunctionCall) otto.Value { return js.re.ToVal(js.ethereum.Miner().HashRate()) } diff --git a/miner/miner.go b/miner/miner.go index bff0026dc4..52b9f2a699 100644 --- a/miner/miner.go +++ b/miner/miner.go @@ -37,6 +37,10 @@ func (self *Miner) Mining() bool { return self.mining } +func (m *Miner) SetGasPrice(price *big.Int) { + m.worker.gasPrice = price +} + func (self *Miner) Start(coinbase common.Address) { self.mining = true self.worker.coinbase = coinbase diff --git a/miner/worker.go b/miner/worker.go index 87d17dfd69..bb8b70c86b 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -72,6 +72,7 @@ type worker struct { proc *core.BlockProcessor coinbase common.Address + gasPrice *big.Int extra []byte currentMu sync.Mutex @@ -93,6 +94,7 @@ func newWorker(coinbase common.Address, eth core.Backend) *worker { eth: eth, mux: eth.EventMux(), recv: make(chan *types.Block), + gasPrice: new(big.Int), chain: eth.ChainManager(), proc: eth.BlockProcessor(), possibleUncles: make(map[common.Hash]*types.Block), @@ -239,6 +241,19 @@ func (self *worker) makeCurrent() { self.current.coinbase.SetGasPool(core.CalcGasLimit(parent)) } +func (w *worker) setGasPrice(p *big.Int) { + w.mu.Lock() + defer w.mu.Unlock() + w.gasPrice = p +} + +func (w *worker) gasprice(pct int64) *big.Int { + p := new(big.Int).Set(w.gasPrice) + p.Div(p, big.NewInt(100)) + p.Mul(p, big.NewInt(pct)) + return p +} + func (self *worker) commitNewWork() { self.mu.Lock() defer self.mu.Unlock() @@ -259,9 +274,22 @@ func (self *worker) commitNewWork() { ignoredTransactors = set.New() ) + var pct int64 = 90 + minprice := self.gasprice(pct) for _, tx := range transactions { // We can skip err. It has already been validated in the tx pool from, _ := tx.From() + + // check if it falls within margin + if tx.GasPrice().Cmp(minprice) < 0 { + // ignore the transaction and transactor. We ignore the transactor + // because nonce will fail after ignoring this transaction so there's + // no point + ignoredTransactors.Add(from) + glog.V(logger.Info).Infof("transaction(%x) below gas price (<%d%% ask price). All sequential txs from this address(%x) will fail\n", tx.Hash().Bytes()[:4], pct, from[:4]) + continue + } + // Move on to the next transaction when the transactor is in ignored transactions set // This may occur when a transaction hits the gas limit. When a gas limit is hit and // the transaction is processed (that could potentially be included in the block) it