diff --git a/cmd/geth/main.go b/cmd/geth/main.go index 0f2438cfd5..1739fbc6b5 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -256,6 +256,12 @@ JavaScript API. See https://github.com/ethereum/go-ethereum/wiki/Javascipt-Conso utils.PProfEanbledFlag, utils.PProfPortFlag, utils.SolcPathFlag, + utils.GpoMinGasPriceFlag, + utils.GpoMaxGasPriceFlag, + utils.GpoFullBlockRatioFlag, + utils.GpobaseStepDownFlag, + utils.GpobaseStepUpFlag, + utils.GpobaseCorrectionFactorFlag, } app.Before = func(ctx *cli.Context) error { utils.SetupLogger(ctx) diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index ec29598fb8..0f5e443e4d 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -276,6 +276,36 @@ var ( Usage: "solidity compiler to be used", Value: "solc", } + GpoMinGasPriceFlag = cli.StringFlag{ + Name: "gpomin", + Usage: "Minimum suggested gas price", + Value: new(big.Int).Mul(big.NewInt(10), common.Szabo).String(), + } + GpoMaxGasPriceFlag = cli.StringFlag{ + Name: "gpomax", + Usage: "Maximum suggested gas price", + Value: new(big.Int).Mul(big.NewInt(1000), common.Szabo).String(), + } + GpoFullBlockRatioFlag = cli.IntFlag{ + Name: "gpofull", + Usage: "Full block threshold for gas price calculation (%)", + Value: 80, + } + GpobaseStepDownFlag = cli.IntFlag{ + Name: "gpobasedown", + Usage: "Suggested gas price base step down ratio (1/1000)", + Value: 10, + } + GpobaseStepUpFlag = cli.IntFlag{ + Name: "gpobaseup", + Usage: "Suggested gas price base step up ratio (1/1000)", + Value: 100, + } + GpobaseCorrectionFactorFlag = cli.IntFlag{ + Name: "gpobasecf", + Usage: "Suggested gas price base correction factor (%)", + Value: 110, + } ) // MakeNAT creates a port mapper from set command line flags. @@ -313,33 +343,39 @@ func MakeEthConfig(clientID, version string, ctx *cli.Context) *eth.Config { clientID += "/" + customName } return ð.Config{ - Name: common.MakeName(clientID, version), - DataDir: ctx.GlobalString(DataDirFlag.Name), - ProtocolVersion: ctx.GlobalInt(ProtocolVersionFlag.Name), - GenesisNonce: ctx.GlobalInt(GenesisNonceFlag.Name), - BlockChainVersion: ctx.GlobalInt(BlockchainVersionFlag.Name), - SkipBcVersionCheck: false, - NetworkId: ctx.GlobalInt(NetworkIdFlag.Name), - LogFile: ctx.GlobalString(LogFileFlag.Name), - Verbosity: ctx.GlobalInt(VerbosityFlag.Name), - LogJSON: ctx.GlobalString(LogJSONFlag.Name), - Etherbase: ctx.GlobalString(EtherbaseFlag.Name), - MinerThreads: ctx.GlobalInt(MinerThreadsFlag.Name), - AccountManager: MakeAccountManager(ctx), - VmDebug: ctx.GlobalBool(VMDebugFlag.Name), - MaxPeers: ctx.GlobalInt(MaxPeersFlag.Name), - MaxPendingPeers: ctx.GlobalInt(MaxPendingPeersFlag.Name), - Port: ctx.GlobalString(ListenPortFlag.Name), - NAT: MakeNAT(ctx), - NatSpec: ctx.GlobalBool(NatspecEnabledFlag.Name), - Discovery: !ctx.GlobalBool(NoDiscoverFlag.Name), - NodeKey: MakeNodeKey(ctx), - Shh: ctx.GlobalBool(WhisperEnabledFlag.Name), - Dial: true, - BootNodes: ctx.GlobalString(BootnodesFlag.Name), - GasPrice: common.String2Big(ctx.GlobalString(GasPriceFlag.Name)), - SolcPath: ctx.GlobalString(SolcPathFlag.Name), - AutoDAG: ctx.GlobalBool(AutoDAGFlag.Name) || ctx.GlobalBool(MiningEnabledFlag.Name), + Name: common.MakeName(clientID, version), + DataDir: ctx.GlobalString(DataDirFlag.Name), + ProtocolVersion: ctx.GlobalInt(ProtocolVersionFlag.Name), + GenesisNonce: ctx.GlobalInt(GenesisNonceFlag.Name), + BlockChainVersion: ctx.GlobalInt(BlockchainVersionFlag.Name), + SkipBcVersionCheck: false, + NetworkId: ctx.GlobalInt(NetworkIdFlag.Name), + LogFile: ctx.GlobalString(LogFileFlag.Name), + Verbosity: ctx.GlobalInt(VerbosityFlag.Name), + LogJSON: ctx.GlobalString(LogJSONFlag.Name), + Etherbase: ctx.GlobalString(EtherbaseFlag.Name), + MinerThreads: ctx.GlobalInt(MinerThreadsFlag.Name), + AccountManager: MakeAccountManager(ctx), + VmDebug: ctx.GlobalBool(VMDebugFlag.Name), + MaxPeers: ctx.GlobalInt(MaxPeersFlag.Name), + MaxPendingPeers: ctx.GlobalInt(MaxPendingPeersFlag.Name), + Port: ctx.GlobalString(ListenPortFlag.Name), + NAT: MakeNAT(ctx), + NatSpec: ctx.GlobalBool(NatspecEnabledFlag.Name), + Discovery: !ctx.GlobalBool(NoDiscoverFlag.Name), + NodeKey: MakeNodeKey(ctx), + Shh: ctx.GlobalBool(WhisperEnabledFlag.Name), + Dial: true, + BootNodes: ctx.GlobalString(BootnodesFlag.Name), + GasPrice: common.String2Big(ctx.GlobalString(GasPriceFlag.Name)), + GpoMinGasPrice: common.String2Big(ctx.GlobalString(GpoMinGasPriceFlag.Name)), + GpoMaxGasPrice: common.String2Big(ctx.GlobalString(GpoMaxGasPriceFlag.Name)), + GpoFullBlockRatio: ctx.GlobalInt(GpoFullBlockRatioFlag.Name), + GpobaseStepDown: ctx.GlobalInt(GpobaseStepDownFlag.Name), + GpobaseStepUp: ctx.GlobalInt(GpobaseStepUpFlag.Name), + GpobaseCorrectionFactor: ctx.GlobalInt(GpobaseCorrectionFactorFlag.Name), + SolcPath: ctx.GlobalString(SolcPathFlag.Name), + AutoDAG: ctx.GlobalBool(AutoDAGFlag.Name) || ctx.GlobalBool(MiningEnabledFlag.Name), } } diff --git a/core/block_processor.go b/core/block_processor.go index 54378b2b90..0ed30ca210 100644 --- a/core/block_processor.go +++ b/core/block_processor.go @@ -260,9 +260,31 @@ func (sm *BlockProcessor) processWithParent(block, parent *types.Block) (logs st putTx(sm.extraDb, tx, block, uint64(i)) } + receiptsRlp := receipts.RlpEncode() + /*if len(receipts) > 0 { + glog.V(logger.Info).Infof("Saving %v receipts, rlp len is %v\n", len(receipts), len(receiptsRlp)) + }*/ + sm.extraDb.Put(append(receiptsPre, block.Hash().Bytes()...), receiptsRlp) + return state.Logs(), nil } +func (self *BlockProcessor) GetBlockReceipts(bhash common.Hash) (receipts types.Receipts, err error) { + var rdata []byte + rdata, err = self.extraDb.Get(append(receiptsPre, bhash[:]...)) + + if err == nil { + err = rlp.DecodeBytes(rdata, &receipts) + } else { + glog.V(logger.Detail).Infof("GetBlockReceipts error %v\n", err) + } + /*if len(receipts) > 0 { + glog.V(logger.Info).Infof("GBR len %v\n", len(receipts)) + }*/ + return + +} + // See YP section 4.3.4. "Block Header Validity" // Validates a block. Returns an error if the block is invalid. func (sm *BlockProcessor) ValidateHeader(block, parent *types.Header, checkPow bool) error { diff --git a/eth/backend.go b/eth/backend.go index d2ec0cc62b..c24b4e8777 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -93,6 +93,13 @@ type Config struct { AccountManager *accounts.Manager SolcPath string + GpoMinGasPrice *big.Int + GpoMaxGasPrice *big.Int + GpoFullBlockRatio int + GpobaseStepDown int + GpobaseStepUp int + GpobaseCorrectionFactor int + // NewDB is used to create databases. // If nil, the default is to create leveldb databases on disk. NewDB func(path string) (common.Database, error) @@ -197,6 +204,13 @@ type Ethereum struct { SolcPath string solc *compiler.Solidity + GpoMinGasPrice *big.Int + GpoMaxGasPrice *big.Int + GpoFullBlockRatio int + GpobaseStepDown int + GpobaseStepUp int + GpobaseCorrectionFactor int + net *p2p.Server eventMux *event.TypeMux miner *miner.Miner @@ -266,22 +280,28 @@ func New(config *Config) (*Ethereum, error) { glog.V(logger.Info).Infof("Blockchain DB Version: %d", config.BlockChainVersion) eth := &Ethereum{ - shutdownChan: make(chan bool), - databasesClosed: make(chan bool), - blockDb: blockDb, - stateDb: stateDb, - extraDb: extraDb, - eventMux: &event.TypeMux{}, - accountManager: config.AccountManager, - DataDir: config.DataDir, - etherbase: common.HexToAddress(config.Etherbase), - clientVersion: config.Name, // TODO should separate from Name - ethVersionId: config.ProtocolVersion, - netVersionId: config.NetworkId, - NatSpec: config.NatSpec, - MinerThreads: config.MinerThreads, - SolcPath: config.SolcPath, - AutoDAG: config.AutoDAG, + shutdownChan: make(chan bool), + databasesClosed: make(chan bool), + blockDb: blockDb, + stateDb: stateDb, + extraDb: extraDb, + eventMux: &event.TypeMux{}, + accountManager: config.AccountManager, + DataDir: config.DataDir, + etherbase: common.HexToAddress(config.Etherbase), + clientVersion: config.Name, // TODO should separate from Name + ethVersionId: config.ProtocolVersion, + netVersionId: config.NetworkId, + NatSpec: config.NatSpec, + MinerThreads: config.MinerThreads, + SolcPath: config.SolcPath, + AutoDAG: config.AutoDAG, + GpoMinGasPrice: config.GpoMinGasPrice, + GpoMaxGasPrice: config.GpoMaxGasPrice, + GpoFullBlockRatio: config.GpoFullBlockRatio, + GpobaseStepDown: config.GpobaseStepDown, + GpobaseStepUp: config.GpobaseStepUp, + GpobaseCorrectionFactor: config.GpobaseCorrectionFactor, } eth.pow = ethash.New() diff --git a/rpc/api.go b/rpc/api.go index e353957348..8b9a080f8e 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -59,7 +59,7 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err case "eth_mining": *reply = api.xeth().IsMining() case "eth_gasPrice": - v := xeth.DefaultGasPrice() + v := api.xeth().DefaultGasPrice() *reply = newHexNum(v.Bytes()) case "eth_accounts": *reply = api.xeth().Accounts() diff --git a/xeth/xeth.go b/xeth/xeth.go index d2f9920846..1044b02f6f 100644 --- a/xeth/xeth.go +++ b/xeth/xeth.go @@ -39,8 +39,11 @@ const ( LogFilterTy ) -func DefaultGas() *big.Int { return new(big.Int).Set(defaultGas) } -func DefaultGasPrice() *big.Int { return new(big.Int).Set(defaultGasPrice) } +func DefaultGas() *big.Int { return new(big.Int).Set(defaultGas) } + +func (self *XEth) DefaultGasPrice() *big.Int { + return self.gpo.SuggestPrice() +} type XEth struct { backend *eth.Ethereum @@ -68,6 +71,8 @@ type XEth struct { // register map[string][]*interface{} // TODO improve return type agent *miner.RemoteAgent + + gpo *eth.GasPriceOracle } func NewTest(eth *eth.Ethereum, frontend Frontend) *XEth { @@ -80,22 +85,23 @@ func NewTest(eth *eth.Ethereum, frontend Frontend) *XEth { // New creates an XEth that uses the given frontend. // If a nil Frontend is provided, a default frontend which // confirms all transactions will be used. -func New(eth *eth.Ethereum, frontend Frontend) *XEth { +func New(ethereum *eth.Ethereum, frontend Frontend) *XEth { xeth := &XEth{ - backend: eth, + backend: ethereum, frontend: frontend, quit: make(chan struct{}), - filterManager: filter.NewFilterManager(eth.EventMux()), + filterManager: filter.NewFilterManager(ethereum.EventMux()), logQueue: make(map[int]*logQueue), blockQueue: make(map[int]*hashQueue), transactionQueue: make(map[int]*hashQueue), messages: make(map[int]*whisperFilter), agent: miner.NewRemoteAgent(), + gpo: eth.NewGasPriceOracle(ethereum), } - if eth.Whisper() != nil { - xeth.whisper = NewWhisper(eth.Whisper()) + if ethereum.Whisper() != nil { + xeth.whisper = NewWhisper(ethereum.Whisper()) } - eth.Miner().Register(xeth.agent) + ethereum.Miner().Register(xeth.agent) if frontend == nil { xeth.frontend = dummyFrontend{} } @@ -829,7 +835,7 @@ func (self *XEth) Call(fromStr, toStr, valueStr, gasStr, gasPriceStr, dataStr st } if msg.gasPrice.Cmp(big.NewInt(0)) == 0 { - msg.gasPrice = DefaultGasPrice() + msg.gasPrice = self.DefaultGasPrice() } block := self.CurrentBlock() @@ -898,7 +904,7 @@ func (self *XEth) Transact(fromStr, toStr, nonceStr, valueStr, gasStr, gasPriceS } if len(gasPriceStr) == 0 { - price = DefaultGasPrice() + price = self.DefaultGasPrice() } else { price = common.Big(gasPriceStr) }