Merge pull request #888 from obscuren/develop

miner, flags: Configurable gas price & log flag change
This commit is contained in:
Jeffrey Wilcke 2015-05-09 04:13:16 -07:00
commit e289b0a1c1
8 changed files with 88 additions and 15 deletions

View File

@ -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())
}

View File

@ -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,

View File

@ -73,7 +73,7 @@ func init() {
utils.DataDirFlag,
utils.ListenPortFlag,
utils.LogFileFlag,
utils.LogLevelFlag,
utils.VerbosityFlag,
utils.MaxPeersFlag,
utils.MaxPendingPeersFlag,
utils.MinerThreadsFlag,

View File

@ -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)),
}
}

View File

@ -5,6 +5,7 @@ import (
"encoding/json"
"fmt"
"io/ioutil"
"math/big"
"os"
"path"
"path/filepath"
@ -55,7 +56,7 @@ type Config struct {
DataDir string
LogFile string
LogLevel int
Verbosity int
LogJSON string
VmDebug bool
NatSpec bool
@ -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()

View File

@ -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

View File

@ -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
}

View File

@ -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() },