From 499f682b48f914ed4af0e32ba446dd0cf56e96b4 Mon Sep 17 00:00:00 2001 From: Determinant Date: Wed, 14 Aug 2019 15:19:28 -0400 Subject: allow manual block generation --- coreth.go | 4 ++++ eth/backend.go | 2 +- eth/config.go | 2 +- eth/gen_config.go | 2 +- examples/payments/main.go | 5 ++++- miner/miner.go | 23 +++++++++++++++++++---- miner/worker.go | 22 +++++++++++++++++++--- 7 files changed, 49 insertions(+), 11 deletions(-) diff --git a/coreth.go b/coreth.go index 0f65ca9..e769d06 100644 --- a/coreth.go +++ b/coreth.go @@ -53,6 +53,10 @@ func (self *ETHChain) Stop() { self.backend.StopPart() } +func (self *ETHChain) GenBlock() { + self.backend.Miner().GenBlock() +} + func (self *ETHChain) AddRemoteTxs(txs []*types.Transaction) []error { return self.backend.TxPool().AddRemotes(txs) } diff --git a/eth/backend.go b/eth/backend.go index 16780cc..d99c099 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -214,7 +214,7 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) { if eth.protocolManager, err = NewProtocolManager(chainConfig, checkpoint, config.SyncMode, config.NetworkId, eth.eventMux, eth.txPool, eth.engine, eth.blockchain, chainDb, cacheLimit, config.Whitelist); err != nil { return nil, err } - eth.miner = miner.New(eth, &config.Miner, chainConfig, eth.EventMux(), eth.engine, eth.isLocalBlock) + eth.miner = miner.New(eth, &config.Miner, chainConfig, eth.EventMux(), eth.engine, eth.isLocalBlock, config.Miner.ManualMining) eth.miner.SetExtra(makeExtraData(config.Miner.ExtraData)) eth.APIBackend = &EthAPIBackend{ctx.ExtRPCEnabled(), eth, nil} diff --git a/eth/config.go b/eth/config.go index 3149c6f..9a462bf 100644 --- a/eth/config.go +++ b/eth/config.go @@ -30,7 +30,7 @@ import ( "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/eth/downloader" "github.com/ethereum/go-ethereum/eth/gasprice" - "github.com/ethereum/go-ethereum/miner" + "github.com/Determinant/coreth/miner" "github.com/ethereum/go-ethereum/params" ) diff --git a/eth/gen_config.go b/eth/gen_config.go index bc4b55b..74c2a3f 100644 --- a/eth/gen_config.go +++ b/eth/gen_config.go @@ -11,7 +11,7 @@ import ( "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/eth/downloader" "github.com/ethereum/go-ethereum/eth/gasprice" - "github.com/ethereum/go-ethereum/miner" + "github.com/Determinant/coreth/miner" "github.com/ethereum/go-ethereum/params" ) diff --git a/examples/payments/main.go b/examples/payments/main.go index 3e675ac..9609359 100644 --- a/examples/payments/main.go +++ b/examples/payments/main.go @@ -55,6 +55,8 @@ func main() { Alloc: core.GenesisAlloc{ genKey.Address: { Balance: genBalance }}, } + config.Miner.ManualMining = true + chainID := chainConfig.ChainID nonce := uint64(1) value := big.NewInt(1000000000000) @@ -69,8 +71,9 @@ func main() { tx := types.NewTransaction(nonce, bob.Address, value, uint64(gasLimit), gasPrice, nil) signedTx, err := types.SignTx(tx, types.NewEIP155Signer(chainID), genKey.PrivateKey); checkError(err) chain.AddLocalTxs([]*types.Transaction{signedTx}) - time.Sleep(5000 * time.Millisecond) + time.Sleep(1000 * time.Millisecond) nonce++ + chain.GenBlock() } c := make(chan os.Signal, 1) diff --git a/miner/miner.go b/miner/miner.go index 969dceb..4e36fed 100644 --- a/miner/miner.go +++ b/miner/miner.go @@ -20,6 +20,7 @@ package miner import ( "fmt" "time" + "math/big" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/types" @@ -27,8 +28,8 @@ import ( "github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/state" - eminer "github.com/ethereum/go-ethereum/miner" ) // Backend wraps all methods required for mining. @@ -38,15 +39,25 @@ type Backend interface { } // Config is the configuration parameters of mining. -type Config = eminer.Config +type Config struct { + Etherbase common.Address `toml:",omitempty"` // Public address for block mining rewards (default = first account) + Notify []string `toml:",omitempty"` // HTTP URL list to be notified of new work packages(only useful in ethash). + ExtraData hexutil.Bytes `toml:",omitempty"` // Block extra data set by the miner + GasFloor uint64 // Target gas floor for mined blocks. + GasCeil uint64 // Target gas ceiling for mined blocks. + GasPrice *big.Int // Minimum gas price for mining a transaction + Recommit time.Duration // The time interval for miner to re-create mining work. + Noverify bool // Disable remote mining solution verification(only useful in ethash). + ManualMining bool +} type Miner struct { w *worker } -func New(eth Backend, config *Config, chainConfig *params.ChainConfig, mux *event.TypeMux, engine consensus.Engine, isLocalBlock func(block *types.Block) bool) *Miner { +func New(eth Backend, config *Config, chainConfig *params.ChainConfig, mux *event.TypeMux, engine consensus.Engine, isLocalBlock func(block *types.Block) bool, manualMining bool) *Miner { return &Miner { - w: newWorker(config, chainConfig, engine, eth, mux, isLocalBlock), + w: newWorker(config, chainConfig, engine, eth, mux, isLocalBlock, manualMining), } } @@ -91,3 +102,7 @@ func (self *Miner) PendingBlock() *types.Block { func (self *Miner) SetEtherbase(addr common.Address) { self.w.setEtherbase(addr) } + +func (self *Miner) GenBlock() { + self.w.genBlock() +} diff --git a/miner/worker.go b/miner/worker.go index b5448d3..5124758 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -180,9 +180,10 @@ type worker struct { skipSealHook func(*task) bool // Method to decide whether skipping the sealing. fullTaskHook func() // Method to call before pushing the full sealing task. resubmitHook func(time.Duration, time.Duration) // Method to call upon updating resubmitting interval. + manualMining bool } -func newWorker(config *Config, chainConfig *params.ChainConfig, engine consensus.Engine, eth Backend, mux *event.TypeMux, isLocalBlock func(*types.Block) bool) *worker { +func newWorker(config *Config, chainConfig *params.ChainConfig, engine consensus.Engine, eth Backend, mux *event.TypeMux, isLocalBlock func(*types.Block) bool, manualMining bool) *worker { worker := &worker{ config: config, chainConfig: chainConfig, @@ -205,6 +206,7 @@ func newWorker(config *Config, chainConfig *params.ChainConfig, engine consensus startCh: make(chan struct{}, 1), resubmitIntervalCh: make(chan time.Duration), resubmitAdjustCh: make(chan *intervalAdjust, resubmitAdjustChanSize), + manualMining: manualMining, } // Subscribe NewTxsEvent for tx pool worker.txsSub = eth.TxPool().SubscribeNewTxsEvent(worker.txsCh) @@ -290,6 +292,16 @@ func (w *worker) close() { close(w.exitCh) } +func (w *worker) genBlock() { + interrupt := new(int32) + *interrupt = commitInterruptNewHead + w.newWorkCh <- &newWorkReq{ + interrupt: interrupt, + noempty: false, + timestamp: time.Now().Unix(), + } +} + // newWorkLoop is a standalone goroutine to submit new mining work upon received events. func (w *worker) newWorkLoop(recommit time.Duration) { var ( @@ -348,12 +360,16 @@ func (w *worker) newWorkLoop(recommit time.Duration) { case <-w.startCh: clearPending(w.chain.CurrentBlock().NumberU64()) timestamp = time.Now().Unix() - commit(false, commitInterruptNewHead) + if !w.manualMining { + commit(false, commitInterruptNewHead) + } case head := <-w.chainHeadCh: clearPending(head.Block.NumberU64()) timestamp = time.Now().Unix() - commit(false, commitInterruptNewHead) + if !w.manualMining { + commit(false, commitInterruptNewHead) + } case <-timer.C: // If mining is running resubmit a new work cycle periodically to pull in -- cgit v1.2.3-70-g09d2