Commit e289b0a1 authored by Jeffrey Wilcke's avatar Jeffrey Wilcke

Merge pull request #888 from obscuren/develop

miner, flags: Configurable gas price & log flag change
parents c8fc4ceb 658ac3c2
......@@ -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())
}
......
......@@ -51,7 +51,7 @@ import _ "net/http/pprof"
const (
ClientIdentifier = "Geth"
Version = "0.9.17"
Version = "0.9.18"
)
var (
......@@ -244,6 +244,7 @@ JavaScript API. See https://github.com/ethereum/go-ethereum/wiki/Javascipt-Conso
utils.MaxPeersFlag,
utils.MaxPendingPeersFlag,
utils.EtherbaseFlag,
utils.GasPriceFlag,
utils.MinerThreadsFlag,
utils.MiningEnabledFlag,
utils.NATFlag,
......@@ -258,7 +259,7 @@ JavaScript API. See https://github.com/ethereum/go-ethereum/wiki/Javascipt-Conso
utils.ProtocolVersionFlag,
utils.NetworkIdFlag,
utils.RPCCORSDomainFlag,
utils.LogLevelFlag,
utils.VerbosityFlag,
utils.BacktraceAtFlag,
utils.LogToStdErrFlag,
utils.LogVModuleFlag,
......
......@@ -73,7 +73,7 @@ func init() {
utils.DataDirFlag,
utils.ListenPortFlag,
utils.LogFileFlag,
utils.LogLevelFlag,
utils.VerbosityFlag,
utils.MaxPeersFlag,
utils.MaxPendingPeersFlag,
utils.MinerThreadsFlag,
......
......@@ -4,6 +4,7 @@ import (
"crypto/ecdsa"
"fmt"
"log"
"math/big"
"net/http"
"os"
"path"
......@@ -116,6 +117,11 @@ var (
Usage: "Public address for block mining rewards. By default the address of your primary account is used",
Value: "primary",
}
GasPriceFlag = cli.StringFlag{
Name: "gasprice",
Usage: "Sets the minimal gasprice when mining transactions",
Value: new(big.Int).Mul(big.NewInt(10), common.Szabo).String(),
}
UnlockedAccountFlag = cli.StringFlag{
Name: "unlock",
......@@ -133,8 +139,8 @@ var (
Name: "logfile",
Usage: "Send log output to a file",
}
LogLevelFlag = cli.IntFlag{
Name: "loglevel",
VerbosityFlag = cli.IntFlag{
Name: "verbosity",
Usage: "Logging verbosity: 0-6 (0=silent, 1=error, 2=warn, 3=info, 4=core, 5=debug, 6=debug detail)",
Value: int(logger.InfoLevel),
}
......@@ -270,7 +276,7 @@ func GetNodeKey(ctx *cli.Context) (key *ecdsa.PrivateKey) {
func MakeEthConfig(clientID, version string, ctx *cli.Context) *eth.Config {
// Set verbosity on glog
glog.SetV(ctx.GlobalInt(LogLevelFlag.Name))
glog.SetV(ctx.GlobalInt(VerbosityFlag.Name))
// Set the log type
//glog.SetToStderr(ctx.GlobalBool(LogToStdErrFlag.Name))
glog.SetToStderr(true)
......@@ -290,7 +296,7 @@ func MakeEthConfig(clientID, version string, ctx *cli.Context) *eth.Config {
SkipBcVersionCheck: false,
NetworkId: ctx.GlobalInt(NetworkIdFlag.Name),
LogFile: ctx.GlobalString(LogFileFlag.Name),
LogLevel: ctx.GlobalInt(LogLevelFlag.Name),
Verbosity: ctx.GlobalInt(VerbosityFlag.Name),
LogJSON: ctx.GlobalString(LogJSONFlag.Name),
Etherbase: ctx.GlobalString(EtherbaseFlag.Name),
MinerThreads: ctx.GlobalInt(MinerThreadsFlag.Name),
......@@ -305,6 +311,7 @@ func MakeEthConfig(clientID, version string, ctx *cli.Context) *eth.Config {
Shh: ctx.GlobalBool(WhisperEnabledFlag.Name),
Dial: true,
BootNodes: ctx.GlobalString(BootnodesFlag.Name),
GasPrice: common.String2Big(ctx.GlobalString(GasPriceFlag.Name)),
}
}
......
......@@ -5,6 +5,7 @@ import (
"encoding/json"
"fmt"
"io/ioutil"
"math/big"
"os"
"path"
"path/filepath"
......@@ -53,12 +54,12 @@ type Config struct {
BlockChainVersion int
SkipBcVersionCheck bool // e.g. blockchain export
DataDir string
LogFile string
LogLevel int
LogJSON string
VmDebug bool
NatSpec bool
DataDir string
LogFile string
Verbosity int
LogJSON string
VmDebug bool
NatSpec bool
MaxPeers int
MaxPendingPeers int
......@@ -76,6 +77,7 @@ type Config struct {
Dial bool
Etherbase string
GasPrice *big.Int
MinerThreads int
AccountManager *accounts.Manager
......@@ -200,7 +202,7 @@ type Ethereum struct {
func New(config *Config) (*Ethereum, error) {
// Bootstrap database
logger.New(config.DataDir, config.LogFile, config.LogLevel)
logger.New(config.DataDir, config.LogFile, config.Verbosity)
if len(config.LogJSON) > 0 {
logger.NewJSONsystem(config.DataDir, config.LogJSON)
}
......@@ -266,6 +268,8 @@ func New(config *Config) (*Ethereum, error) {
eth.blockProcessor = core.NewBlockProcessor(stateDb, extraDb, eth.pow, eth.txPool, eth.chainManager, eth.EventMux())
eth.chainManager.SetProcessor(eth.blockProcessor)
eth.miner = miner.New(eth, eth.pow, config.MinerThreads)
eth.miner.SetGasPrice(config.GasPrice)
eth.protocolManager = NewProtocolManager(config.ProtocolVersion, config.NetworkId, eth.eventMux, eth.txPool, eth.chainManager, eth.downloader)
if config.Shh {
eth.whisper = whisper.New()
......
......@@ -37,6 +37,15 @@ func (self *Miner) Mining() bool {
return self.mining
}
func (m *Miner) SetGasPrice(price *big.Int) {
// FIXME block tests set a nil gas price. Quick dirty fix
if price == nil {
return
}
m.worker.gasPrice = price
}
func (self *Miner) Start(coinbase common.Address) {
self.mining = true
self.worker.coinbase = coinbase
......
......@@ -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),
......@@ -123,6 +125,9 @@ func (self *worker) pendingBlock() *types.Block {
}
func (self *worker) start() {
self.mu.Lock()
defer self.mu.Unlock()
// spin up agents
for _, agent := range self.agents {
agent.Start()
......@@ -132,6 +137,9 @@ func (self *worker) start() {
}
func (self *worker) stop() {
self.mu.Lock()
defer self.mu.Unlock()
if atomic.LoadInt32(&self.mining) == 1 {
// stop all agents
for _, agent := range self.agents {
......@@ -144,6 +152,9 @@ func (self *worker) stop() {
}
func (self *worker) register(agent Agent) {
self.mu.Lock()
defer self.mu.Unlock()
self.agents = append(self.agents, agent)
agent.SetReturnCh(self.recv)
}
......@@ -239,6 +250,12 @@ 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 (self *worker) commitNewWork() {
self.mu.Lock()
defer self.mu.Unlock()
......@@ -259,9 +276,23 @@ func (self *worker) commitNewWork() {
ignoredTransactors = set.New()
)
const pct = int64(90)
// calculate the minimal gas price the miner accepts when sorting out transactions.
minprice := gasprice(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
......@@ -383,3 +414,12 @@ func (self *worker) HashRate() int64 {
return tot
}
// gasprice calculates a reduced gas price based on the pct
// XXX Use big.Rat?
func gasprice(price *big.Int, pct int64) *big.Int {
p := new(big.Int).Set(price)
p.Div(p, big.NewInt(100))
p.Mul(p, big.NewInt(pct))
return p
}
......@@ -103,7 +103,7 @@ func testEthConfig() *eth.Config {
return &eth.Config{
DataDir: common.DefaultDataDir(),
LogLevel: 5,
Verbosity: 5,
Etherbase: "primary",
AccountManager: accounts.NewManager(ks),
NewDB: func(path string) (common.Database, error) { return ethdb.NewMemDatabase() },
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment