aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDeterminant <[email protected]>2019-08-14 23:55:12 -0400
committerDeterminant <[email protected]>2019-08-14 23:55:12 -0400
commit03513e267d25b5086b3f905b6d1bc5635fcda845 (patch)
treed2c800a6d04f7def64b4061ceb97f5faa13cf8ea
parent63fc17f85121f84d597742a49b99ab3d022aa6bd (diff)
...
-rw-r--r--cmd/utils/flags.go5
-rw-r--r--consensus/dummy/consensus.go14
-rw-r--r--coreth.go12
-rw-r--r--eth/backend.go10
-rw-r--r--examples/payments/main.go19
-rw-r--r--miner/miner.go5
-rw-r--r--miner/worker.go20
7 files changed, 60 insertions, 25 deletions
diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go
index 54dc9cd..d9f0b41 100644
--- a/cmd/utils/flags.go
+++ b/cmd/utils/flags.go
@@ -34,6 +34,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/fdlimit"
"github.com/ethereum/go-ethereum/consensus"
+ "github.com/Determinant/coreth/consensus/dummy"
"github.com/ethereum/go-ethereum/consensus/clique"
"github.com/ethereum/go-ethereum/consensus/ethash"
"github.com/ethereum/go-ethereum/core"
@@ -49,7 +50,7 @@ import (
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/metrics"
"github.com/ethereum/go-ethereum/metrics/influxdb"
- "github.com/ethereum/go-ethereum/miner"
+ "github.com/Determinant/coreth/miner"
"github.com/Determinant/coreth/node"
"github.com/ethereum/go-ethereum/p2p"
"github.com/ethereum/go-ethereum/p2p/discv5"
@@ -1481,7 +1482,7 @@ func RegisterEthService(stack *node.Node, cfg *eth.Config) {
panic("not supported")
} else {
err = stack.Register(func(ctx *node.ServiceContext) (node.Service, error) {
- fullNode, err := eth.New(ctx, cfg)
+ fullNode, err := eth.New(ctx, cfg, &dummy.ConsensusCallbacks{})
if fullNode != nil && cfg.LightServ > 0 {
panic("not supported")
}
diff --git a/consensus/dummy/consensus.go b/consensus/dummy/consensus.go
index 6b03844..0086581 100644
--- a/consensus/dummy/consensus.go
+++ b/consensus/dummy/consensus.go
@@ -17,7 +17,16 @@ import (
"github.com/ethereum/go-ethereum/rpc"
)
+type ConsensusCallbacks struct {
+ OnSeal func(*types.Block)
+}
+
type DummyEngine struct {
+ cb *ConsensusCallbacks
+}
+
+func NewDummyEngine(cb *ConsensusCallbacks) *DummyEngine {
+ return &DummyEngine { cb: cb }
}
var (
@@ -192,8 +201,9 @@ uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error) {
}
func (self *DummyEngine) Seal(chain consensus.ChainReader, block *types.Block, results chan<- *types.Block, stop <-chan struct{}) error {
- //time.Sleep(1000 * time.Millisecond)
- fmt.Printf("sealed %s\n", block.ParentHash().String())
+ if self.cb.OnSeal != nil {
+ self.cb.OnSeal(block)
+ }
results <- block
return nil
}
diff --git a/coreth.go b/coreth.go
index e769d06..e5bbef9 100644
--- a/coreth.go
+++ b/coreth.go
@@ -10,6 +10,7 @@ import (
"github.com/ethereum/go-ethereum/event"
"github.com/Determinant/coreth/eth"
"github.com/Determinant/coreth/node"
+ "github.com/Determinant/coreth/consensus/dummy"
"github.com/ethereum/go-ethereum/crypto"
)
@@ -19,10 +20,10 @@ type Hash = common.Hash
type ETHChain struct {
backend *eth.Ethereum
+ cb *dummy.ConsensusCallbacks
}
-
func isLocalBlock(block *types.Block) bool {
return false
}
@@ -33,8 +34,9 @@ func NewETHChain(config *eth.Config, etherBase *common.Address) *ETHChain {
}
mux := new(event.TypeMux)
ctx := node.NewServiceContext(mux)
- backend, _ := eth.New(&ctx, config)
- chain := &ETHChain { backend: backend }
+ cb := new(dummy.ConsensusCallbacks)
+ backend, _ := eth.New(&ctx, config, cb)
+ chain := &ETHChain { backend: backend, cb: cb }
if etherBase == nil {
etherBase = &common.Address{
1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -65,6 +67,10 @@ func (self *ETHChain) AddLocalTxs(txs []*types.Transaction) []error {
return self.backend.TxPool().AddLocals(txs)
}
+func (self *ETHChain) SetOnSeal(cb func(*types.Block)) {
+ self.cb.OnSeal = cb
+}
+
type Key struct {
Address common.Address
PrivateKey *ecdsa.PrivateKey
diff --git a/eth/backend.go b/eth/backend.go
index d99c099..a2cda02 100644
--- a/eth/backend.go
+++ b/eth/backend.go
@@ -116,7 +116,7 @@ func (s *Ethereum) SetContractBackend(backend bind.ContractBackend) {
// New creates a new Ethereum object (including the
// initialisation of the common Ethereum object)
-func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
+func New(ctx *node.ServiceContext, config *Config, cb *dummy.ConsensusCallbacks) (*Ethereum, error) {
// Ensure configuration values are compatible and sane
if config.SyncMode == downloader.LightSync {
return nil, errors.New("can't run eth.Ethereum in light sync mode, use les.LightEthereum")
@@ -150,7 +150,7 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
chainDb: chainDb,
eventMux: ctx.EventMux,
accountManager: ctx.AccountManager,
- engine: CreateConsensusEngine(ctx, chainConfig, &config.Ethash, config.Miner.Notify, config.Miner.Noverify, chainDb),
+ engine: CreateConsensusEngine(ctx, chainConfig, &config.Ethash, config.Miner.Notify, config.Miner.Noverify, chainDb, cb),
shutdownChan: make(chan bool),
networkID: config.NetworkId,
gasPrice: config.Miner.GasPrice,
@@ -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, config.Miner.ManualMining)
+ eth.miner = miner.New(eth, &config.Miner, chainConfig, eth.EventMux(), eth.engine, eth.isLocalBlock)
eth.miner.SetExtra(makeExtraData(config.Miner.ExtraData))
eth.APIBackend = &EthAPIBackend{ctx.ExtRPCEnabled(), eth, nil}
@@ -245,8 +245,8 @@ func makeExtraData(extra []byte) []byte {
}
// CreateConsensusEngine creates the required type of consensus engine instance for an Ethereum service
-func CreateConsensusEngine(ctx *node.ServiceContext, chainConfig *params.ChainConfig, config *ethash.Config, notify []string, noverify bool, db ethdb.Database) consensus.Engine {
- return new(dummy.DummyEngine)
+func CreateConsensusEngine(ctx *node.ServiceContext, chainConfig *params.ChainConfig, config *ethash.Config, notify []string, noverify bool, db ethdb.Database, cb *dummy.ConsensusCallbacks) consensus.Engine {
+ return dummy.NewDummyEngine(cb)
}
// APIs return the collection of RPC services the ethereum package offers.
diff --git a/examples/payments/main.go b/examples/payments/main.go
index 46e4e58..8a1dca8 100644
--- a/examples/payments/main.go
+++ b/examples/payments/main.go
@@ -9,7 +9,6 @@ import (
"math/big"
//"encoding/hex"
"github.com/ethereum/go-ethereum/core/types"
- //"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core"
"github.com/Determinant/coreth/eth"
@@ -42,7 +41,7 @@ func main() {
Ethash: nil,
}
- genBalance := big.NewInt(1000000000000000000)
+ genBalance := big.NewInt(100000000000000000)
genKey, _ := coreth.NewKey(rand.Reader)
config.Genesis = &core.Genesis{
@@ -56,24 +55,32 @@ func main() {
}
config.Miner.ManualMining = true
+ config.Miner.ManualUncle = true
chainID := chainConfig.ChainID
nonce := uint64(0)
value := big.NewInt(1000000000000)
gasLimit := 21000
- gasPrice := big.NewInt(1000)
+ gasPrice := big.NewInt(1000000000)
bob, err := coreth.NewKey(rand.Reader); checkError(err)
chain := coreth.NewETHChain(&config, nil)
+ chain.SetOnSeal(func(block *types.Block) {
+ go func() {
+ time.Sleep(1000 * time.Millisecond)
+ chain.GenBlock()
+ }()
+ })
chain.Start()
+ chain.GenBlock()
for i := 0; i < 10; i++ {
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(2000 * time.Millisecond)
+ _ = signedTx
+ chain.AddRemoteTxs([]*types.Transaction{signedTx})
+ 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 4e36fed..53a37b0 100644
--- a/miner/miner.go
+++ b/miner/miner.go
@@ -49,15 +49,16 @@ type Config struct {
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
+ ManualUncle 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, manualMining bool) *Miner {
+func New(eth Backend, config *Config, chainConfig *params.ChainConfig, mux *event.TypeMux, engine consensus.Engine, isLocalBlock func(block *types.Block) bool) *Miner {
return &Miner {
- w: newWorker(config, chainConfig, engine, eth, mux, isLocalBlock, manualMining),
+ w: newWorker(config, chainConfig, engine, eth, mux, isLocalBlock),
}
}
diff --git a/miner/worker.go b/miner/worker.go
index cb0ec7b..c1a82ce 100644
--- a/miner/worker.go
+++ b/miner/worker.go
@@ -181,9 +181,10 @@ type worker struct {
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
+ manualUncle bool
}
-func newWorker(config *Config, chainConfig *params.ChainConfig, engine consensus.Engine, eth Backend, mux *event.TypeMux, isLocalBlock func(*types.Block) bool, manualMining bool) *worker {
+func newWorker(config *Config, chainConfig *params.ChainConfig, engine consensus.Engine, eth Backend, mux *event.TypeMux, isLocalBlock func(*types.Block) bool) *worker {
worker := &worker{
config: config,
chainConfig: chainConfig,
@@ -206,7 +207,8 @@ 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,
+ manualMining: config.ManualMining,
+ manualUncle: config.ManualUncle,
}
// Subscribe NewTxsEvent for tx pool
worker.txsSub = eth.TxPool().SubscribeNewTxsEvent(worker.txsCh)
@@ -361,6 +363,7 @@ func (w *worker) newWorkLoop(recommit time.Duration) {
clearPending(w.chain.CurrentBlock().NumberU64())
timestamp = time.Now().Unix()
if !w.manualMining {
+ log.Warn("commit ch")
commit(false, commitInterruptNewHead)
}
@@ -368,6 +371,7 @@ func (w *worker) newWorkLoop(recommit time.Duration) {
clearPending(head.Block.NumberU64())
timestamp = time.Now().Unix()
if !w.manualMining {
+ log.Warn("commit update")
commit(false, commitInterruptNewHead)
}
@@ -380,6 +384,7 @@ func (w *worker) newWorkLoop(recommit time.Duration) {
timer.Reset(recommit)
continue
}
+ log.Warn("commit resubmit")
commit(true, commitInterruptResubmit)
}
@@ -445,7 +450,8 @@ func (w *worker) mainLoop() {
}
// If our mining block contains less than 2 uncle blocks,
// add the new uncle block if valid and regenerate a mining block.
- if w.isRunning() && w.current != nil && w.current.uncles.Cardinality() < 2 {
+ if w.isRunning() && w.current != nil && w.current.uncles.Cardinality() < 2 && !w.manualUncle {
+ log.Warn("wtf")
start := time.Now()
if err := w.commitUncle(w.current, ev.Block.Header()); err == nil {
var uncles []*types.Header
@@ -611,7 +617,9 @@ func (w *worker) resultLoop() {
logs = append(logs, receipt.Logs...)
}
// Commit block and state to database.
+ //fmt.Printf("parent1: %s\n", w.chain.CurrentBlock().Hash().String())
stat, err := w.chain.WriteBlockWithState(block, receipts, task.state)
+ //fmt.Printf("parent2: %s\n", w.chain.CurrentBlock().Hash().String())
if err != nil {
log.Error("Failed writing block to chain", "err", err)
continue
@@ -938,9 +946,10 @@ func (w *worker) commitNewWork(interrupt *int32, noempty bool, timestamp int64)
commitUncles(w.localUncles)
commitUncles(w.remoteUncles)
- if !noempty {
+ if !noempty && !w.manualUncle {
// Create an empty block based on temporary copied state for sealing in advance without waiting block
// execution finished.
+ log.Warn("commit n1")
w.commit(uncles, nil, false, tstart)
}
@@ -951,7 +960,7 @@ func (w *worker) commitNewWork(interrupt *int32, noempty bool, timestamp int64)
return
}
// Short circuit if there is no available pending transactions
- if len(pending) == 0 {
+ if len(pending) == 0 && !w.manualMining {
w.updateSnapshot()
return
}
@@ -975,6 +984,7 @@ func (w *worker) commitNewWork(interrupt *int32, noempty bool, timestamp int64)
return
}
}
+ log.Warn("commit n2")
w.commit(uncles, w.fullTaskHook, true, tstart)
}