forked from cerc-io/plugeth
all: use (blocking) event package instead of ethreact
This commit is contained in:
parent
6906904896
commit
36cdab2068
@ -8,7 +8,6 @@ import (
|
|||||||
|
|
||||||
"github.com/ethereum/eth-go/ethcrypto"
|
"github.com/ethereum/eth-go/ethcrypto"
|
||||||
"github.com/ethereum/eth-go/ethlog"
|
"github.com/ethereum/eth-go/ethlog"
|
||||||
"github.com/ethereum/eth-go/ethreact"
|
|
||||||
"github.com/ethereum/eth-go/ethutil"
|
"github.com/ethereum/eth-go/ethutil"
|
||||||
"github.com/obscuren/sha3"
|
"github.com/obscuren/sha3"
|
||||||
)
|
)
|
||||||
@ -16,7 +15,7 @@ import (
|
|||||||
var powlogger = ethlog.NewLogger("POW")
|
var powlogger = ethlog.NewLogger("POW")
|
||||||
|
|
||||||
type PoW interface {
|
type PoW interface {
|
||||||
Search(block *Block, reactChan chan ethreact.Event) []byte
|
Search(block *Block, stop <-chan struct{}) []byte
|
||||||
Verify(hash []byte, diff *big.Int, nonce []byte) bool
|
Verify(hash []byte, diff *big.Int, nonce []byte) bool
|
||||||
GetHashrate() int64
|
GetHashrate() int64
|
||||||
Turbo(bool)
|
Turbo(bool)
|
||||||
@ -36,7 +35,7 @@ func (pow *EasyPow) Turbo(on bool) {
|
|||||||
pow.turbo = on
|
pow.turbo = on
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pow *EasyPow) Search(block *Block, reactChan chan ethreact.Event) []byte {
|
func (pow *EasyPow) Search(block *Block, stop <-chan struct{}) []byte {
|
||||||
r := rand.New(rand.NewSource(time.Now().UnixNano()))
|
r := rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||||
hash := block.HashNoNonce()
|
hash := block.HashNoNonce()
|
||||||
diff := block.Difficulty
|
diff := block.Difficulty
|
||||||
@ -46,7 +45,7 @@ func (pow *EasyPow) Search(block *Block, reactChan chan ethreact.Event) []byte {
|
|||||||
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-reactChan:
|
case <-stop:
|
||||||
powlogger.Infoln("Breaking from mining")
|
powlogger.Infoln("Breaking from mining")
|
||||||
return nil
|
return nil
|
||||||
default:
|
default:
|
||||||
|
10
ethchain/events.go
Normal file
10
ethchain/events.go
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
package ethchain
|
||||||
|
|
||||||
|
type TxEvent struct {
|
||||||
|
Type int // TxPre || TxPost
|
||||||
|
Tx *Transaction
|
||||||
|
}
|
||||||
|
|
||||||
|
type NewBlockEvent struct {
|
||||||
|
Block *Block
|
||||||
|
}
|
@ -11,11 +11,10 @@ import (
|
|||||||
|
|
||||||
"github.com/ethereum/eth-go/ethcrypto"
|
"github.com/ethereum/eth-go/ethcrypto"
|
||||||
"github.com/ethereum/eth-go/ethlog"
|
"github.com/ethereum/eth-go/ethlog"
|
||||||
"github.com/ethereum/eth-go/ethreact"
|
|
||||||
"github.com/ethereum/eth-go/ethstate"
|
"github.com/ethereum/eth-go/ethstate"
|
||||||
"github.com/ethereum/eth-go/ethutil"
|
"github.com/ethereum/eth-go/ethutil"
|
||||||
"github.com/ethereum/eth-go/ethwire"
|
"github.com/ethereum/eth-go/ethwire"
|
||||||
"github.com/ethereum/eth-go/eventer"
|
"github.com/ethereum/eth-go/event"
|
||||||
)
|
)
|
||||||
|
|
||||||
var statelogger = ethlog.NewLogger("STATE")
|
var statelogger = ethlog.NewLogger("STATE")
|
||||||
@ -37,7 +36,6 @@ type EthManager interface {
|
|||||||
BlockChain() *BlockChain
|
BlockChain() *BlockChain
|
||||||
TxPool() *TxPool
|
TxPool() *TxPool
|
||||||
Broadcast(msgType ethwire.MsgType, data []interface{})
|
Broadcast(msgType ethwire.MsgType, data []interface{})
|
||||||
Reactor() *ethreact.ReactorEngine
|
|
||||||
PeerCount() int
|
PeerCount() int
|
||||||
IsMining() bool
|
IsMining() bool
|
||||||
IsListening() bool
|
IsListening() bool
|
||||||
@ -45,7 +43,7 @@ type EthManager interface {
|
|||||||
KeyManager() *ethcrypto.KeyManager
|
KeyManager() *ethcrypto.KeyManager
|
||||||
ClientIdentity() ethwire.ClientIdentity
|
ClientIdentity() ethwire.ClientIdentity
|
||||||
Db() ethutil.Database
|
Db() ethutil.Database
|
||||||
Eventer() *eventer.EventMachine
|
EventMux() *event.TypeMux
|
||||||
}
|
}
|
||||||
|
|
||||||
type StateManager struct {
|
type StateManager struct {
|
||||||
@ -73,8 +71,7 @@ type StateManager struct {
|
|||||||
// 'Process' & canonical validation.
|
// 'Process' & canonical validation.
|
||||||
lastAttemptedBlock *Block
|
lastAttemptedBlock *Block
|
||||||
|
|
||||||
// Quit chan
|
events event.Subscription
|
||||||
quit chan bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewStateManager(ethereum EthManager) *StateManager {
|
func NewStateManager(ethereum EthManager) *StateManager {
|
||||||
@ -83,7 +80,6 @@ func NewStateManager(ethereum EthManager) *StateManager {
|
|||||||
Pow: &EasyPow{},
|
Pow: &EasyPow{},
|
||||||
eth: ethereum,
|
eth: ethereum,
|
||||||
bc: ethereum.BlockChain(),
|
bc: ethereum.BlockChain(),
|
||||||
quit: make(chan bool),
|
|
||||||
}
|
}
|
||||||
sm.transState = ethereum.BlockChain().CurrentBlock.State().Copy()
|
sm.transState = ethereum.BlockChain().CurrentBlock.State().Copy()
|
||||||
sm.miningState = ethereum.BlockChain().CurrentBlock.State().Copy()
|
sm.miningState = ethereum.BlockChain().CurrentBlock.State().Copy()
|
||||||
@ -93,25 +89,18 @@ func NewStateManager(ethereum EthManager) *StateManager {
|
|||||||
|
|
||||||
func (self *StateManager) Start() {
|
func (self *StateManager) Start() {
|
||||||
statelogger.Debugln("Starting state manager")
|
statelogger.Debugln("Starting state manager")
|
||||||
|
self.events = self.eth.EventMux().Subscribe(Blocks(nil))
|
||||||
go self.updateThread()
|
go self.updateThread()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *StateManager) Stop() {
|
func (self *StateManager) Stop() {
|
||||||
statelogger.Debugln("Stopping state manager")
|
statelogger.Debugln("Stopping state manager")
|
||||||
|
self.events.Unsubscribe()
|
||||||
close(self.quit)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *StateManager) updateThread() {
|
func (self *StateManager) updateThread() {
|
||||||
blockChan := self.eth.Eventer().Register("blocks")
|
for ev := range self.events.Chan() {
|
||||||
|
for _, block := range ev.(Blocks) {
|
||||||
out:
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case event := <-blockChan:
|
|
||||||
blocks := event.Data.(Blocks)
|
|
||||||
for _, block := range blocks {
|
|
||||||
err := self.Process(block, false)
|
err := self.Process(block, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
statelogger.Infoln(err)
|
statelogger.Infoln(err)
|
||||||
@ -120,10 +109,6 @@ out:
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
case <-self.quit:
|
|
||||||
break out
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -202,7 +187,7 @@ done:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Notify all subscribers
|
// Notify all subscribers
|
||||||
self.eth.Reactor().Post("newTx:post", tx)
|
self.eth.EventMux().Post(TxEvent{TxPost, tx})
|
||||||
|
|
||||||
receipts = append(receipts, receipt)
|
receipts = append(receipts, receipt)
|
||||||
handled = append(handled, tx)
|
handled = append(handled, tx)
|
||||||
@ -293,7 +278,7 @@ func (sm *StateManager) Process(block *Block, dontReact bool) (err error) {
|
|||||||
|
|
||||||
statelogger.Infof("Imported block #%d (%x...)\n", block.Number, block.Hash()[0:4])
|
statelogger.Infof("Imported block #%d (%x...)\n", block.Number, block.Hash()[0:4])
|
||||||
if dontReact == false {
|
if dontReact == false {
|
||||||
sm.eth.Reactor().Post("newBlock", block)
|
sm.eth.EventMux().Post(NewBlockEvent{block})
|
||||||
|
|
||||||
state.Manifest().Reset()
|
state.Manifest().Reset()
|
||||||
}
|
}
|
||||||
@ -434,7 +419,7 @@ func (sm *StateManager) createBloomFilter(state *ethstate.State) *BloomFilter {
|
|||||||
bloomf.Set(msg.From)
|
bloomf.Set(msg.From)
|
||||||
}
|
}
|
||||||
|
|
||||||
sm.eth.Reactor().Post("messages", state.Manifest().Messages)
|
sm.eth.EventMux().Post(state.Manifest().Messages)
|
||||||
|
|
||||||
return bloomf
|
return bloomf
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@ type TxMsgTy byte
|
|||||||
const (
|
const (
|
||||||
TxPre = iota
|
TxPre = iota
|
||||||
TxPost
|
TxPost
|
||||||
|
|
||||||
minGasPrice = 1000000
|
minGasPrice = 1000000
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -160,7 +161,7 @@ out:
|
|||||||
txplogger.Debugf("(t) %x => %x (%v) %x\n", tx.Sender()[:4], tmp, tx.Value, tx.Hash())
|
txplogger.Debugf("(t) %x => %x (%v) %x\n", tx.Sender()[:4], tmp, tx.Value, tx.Hash())
|
||||||
|
|
||||||
// Notify the subscribers
|
// Notify the subscribers
|
||||||
pool.Ethereum.Reactor().Post("newTx:pre", tx)
|
pool.Ethereum.EventMux().Post(TxEvent{TxPre, tx})
|
||||||
}
|
}
|
||||||
case <-pool.quit:
|
case <-pool.quit:
|
||||||
break out
|
break out
|
||||||
|
54
ethereum.go
54
ethereum.go
@ -17,12 +17,11 @@ import (
|
|||||||
"github.com/ethereum/eth-go/ethchain"
|
"github.com/ethereum/eth-go/ethchain"
|
||||||
"github.com/ethereum/eth-go/ethcrypto"
|
"github.com/ethereum/eth-go/ethcrypto"
|
||||||
"github.com/ethereum/eth-go/ethlog"
|
"github.com/ethereum/eth-go/ethlog"
|
||||||
"github.com/ethereum/eth-go/ethreact"
|
|
||||||
"github.com/ethereum/eth-go/ethrpc"
|
"github.com/ethereum/eth-go/ethrpc"
|
||||||
"github.com/ethereum/eth-go/ethstate"
|
"github.com/ethereum/eth-go/ethstate"
|
||||||
"github.com/ethereum/eth-go/ethutil"
|
"github.com/ethereum/eth-go/ethutil"
|
||||||
"github.com/ethereum/eth-go/ethwire"
|
"github.com/ethereum/eth-go/ethwire"
|
||||||
"github.com/ethereum/eth-go/eventer"
|
"github.com/ethereum/eth-go/event"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -60,7 +59,7 @@ type Ethereum struct {
|
|||||||
// The block pool
|
// The block pool
|
||||||
blockPool *BlockPool
|
blockPool *BlockPool
|
||||||
// Eventer
|
// Eventer
|
||||||
eventer *eventer.EventMachine
|
eventMux *event.TypeMux
|
||||||
// Peers
|
// Peers
|
||||||
peers *list.List
|
peers *list.List
|
||||||
// Nonce
|
// Nonce
|
||||||
@ -85,8 +84,6 @@ type Ethereum struct {
|
|||||||
|
|
||||||
listening bool
|
listening bool
|
||||||
|
|
||||||
reactor *ethreact.ReactorEngine
|
|
||||||
|
|
||||||
RpcServer *ethrpc.JsonRpcServer
|
RpcServer *ethrpc.JsonRpcServer
|
||||||
|
|
||||||
keyManager *ethcrypto.KeyManager
|
keyManager *ethcrypto.KeyManager
|
||||||
@ -129,8 +126,7 @@ func New(db ethutil.Database, clientIdentity ethwire.ClientIdentity, keyManager
|
|||||||
isUpToDate: true,
|
isUpToDate: true,
|
||||||
filters: make(map[int]*ethchain.Filter),
|
filters: make(map[int]*ethchain.Filter),
|
||||||
}
|
}
|
||||||
ethereum.reactor = ethreact.New()
|
ethereum.eventMux = event.NewTypeMux()
|
||||||
ethereum.eventer = eventer.New()
|
|
||||||
|
|
||||||
ethereum.blockPool = NewBlockPool(ethereum)
|
ethereum.blockPool = NewBlockPool(ethereum)
|
||||||
ethereum.txPool = ethchain.NewTxPool(ethereum)
|
ethereum.txPool = ethchain.NewTxPool(ethereum)
|
||||||
@ -143,10 +139,6 @@ func New(db ethutil.Database, clientIdentity ethwire.ClientIdentity, keyManager
|
|||||||
return ethereum, nil
|
return ethereum, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Ethereum) Reactor() *ethreact.ReactorEngine {
|
|
||||||
return s.reactor
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Ethereum) KeyManager() *ethcrypto.KeyManager {
|
func (s *Ethereum) KeyManager() *ethcrypto.KeyManager {
|
||||||
return s.keyManager
|
return s.keyManager
|
||||||
}
|
}
|
||||||
@ -169,8 +161,8 @@ func (s *Ethereum) TxPool() *ethchain.TxPool {
|
|||||||
func (s *Ethereum) BlockPool() *BlockPool {
|
func (s *Ethereum) BlockPool() *BlockPool {
|
||||||
return s.blockPool
|
return s.blockPool
|
||||||
}
|
}
|
||||||
func (s *Ethereum) Eventer() *eventer.EventMachine {
|
func (s *Ethereum) EventMux() *event.TypeMux {
|
||||||
return s.eventer
|
return s.eventMux
|
||||||
}
|
}
|
||||||
func (self *Ethereum) Db() ethutil.Database {
|
func (self *Ethereum) Db() ethutil.Database {
|
||||||
return self.db
|
return self.db
|
||||||
@ -376,7 +368,7 @@ func (s *Ethereum) removePeerElement(e *list.Element) {
|
|||||||
|
|
||||||
s.peers.Remove(e)
|
s.peers.Remove(e)
|
||||||
|
|
||||||
s.reactor.Post("peerList", s.peers)
|
s.eventMux.Post(PeerListEvent{s.peers})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Ethereum) RemovePeer(p *Peer) {
|
func (s *Ethereum) RemovePeer(p *Peer) {
|
||||||
@ -400,7 +392,6 @@ func (s *Ethereum) reapDeadPeerHandler() {
|
|||||||
|
|
||||||
// Start the ethereum
|
// Start the ethereum
|
||||||
func (s *Ethereum) Start(seed bool) {
|
func (s *Ethereum) Start(seed bool) {
|
||||||
s.reactor.Start()
|
|
||||||
s.blockPool.Start()
|
s.blockPool.Start()
|
||||||
s.stateManager.Start()
|
s.stateManager.Start()
|
||||||
|
|
||||||
@ -524,8 +515,7 @@ func (s *Ethereum) Stop() {
|
|||||||
}
|
}
|
||||||
s.txPool.Stop()
|
s.txPool.Stop()
|
||||||
s.stateManager.Stop()
|
s.stateManager.Stop()
|
||||||
s.reactor.Flush()
|
s.eventMux.Stop()
|
||||||
s.reactor.Stop()
|
|
||||||
s.blockPool.Stop()
|
s.blockPool.Stop()
|
||||||
|
|
||||||
ethlogger.Infoln("Server stopped")
|
ethlogger.Infoln("Server stopped")
|
||||||
@ -584,10 +574,10 @@ out:
|
|||||||
select {
|
select {
|
||||||
case <-upToDateTimer.C:
|
case <-upToDateTimer.C:
|
||||||
if self.IsUpToDate() && !self.isUpToDate {
|
if self.IsUpToDate() && !self.isUpToDate {
|
||||||
self.reactor.Post("chainSync", false)
|
self.eventMux.Post(ChainSyncEvent{false})
|
||||||
self.isUpToDate = true
|
self.isUpToDate = true
|
||||||
} else if !self.IsUpToDate() && self.isUpToDate {
|
} else if !self.IsUpToDate() && self.isUpToDate {
|
||||||
self.reactor.Post("chainSync", true)
|
self.eventMux.Post(ChainSyncEvent{true})
|
||||||
self.isUpToDate = false
|
self.isUpToDate = false
|
||||||
}
|
}
|
||||||
case <-self.quit:
|
case <-self.quit:
|
||||||
@ -623,33 +613,24 @@ func (self *Ethereum) GetFilter(id int) *ethchain.Filter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (self *Ethereum) filterLoop() {
|
func (self *Ethereum) filterLoop() {
|
||||||
blockChan := make(chan ethreact.Event, 5)
|
|
||||||
messageChan := make(chan ethreact.Event, 5)
|
|
||||||
// Subscribe to events
|
// Subscribe to events
|
||||||
reactor := self.Reactor()
|
events := self.eventMux.Subscribe(ethchain.NewBlockEvent{}, ethstate.Messages(nil))
|
||||||
reactor.Subscribe("newBlock", blockChan)
|
for event := range events.Chan() {
|
||||||
reactor.Subscribe("messages", messageChan)
|
switch event := event.(type) {
|
||||||
out:
|
case ethchain.NewBlockEvent:
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case <-self.quit:
|
|
||||||
break out
|
|
||||||
case block := <-blockChan:
|
|
||||||
if block, ok := block.Resource.(*ethchain.Block); ok {
|
|
||||||
self.filterMu.RLock()
|
self.filterMu.RLock()
|
||||||
for _, filter := range self.filters {
|
for _, filter := range self.filters {
|
||||||
if filter.BlockCallback != nil {
|
if filter.BlockCallback != nil {
|
||||||
filter.BlockCallback(block)
|
filter.BlockCallback(event.Block)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.filterMu.RUnlock()
|
self.filterMu.RUnlock()
|
||||||
}
|
|
||||||
case msg := <-messageChan:
|
case ethstate.Messages:
|
||||||
if messages, ok := msg.Resource.(ethstate.Messages); ok {
|
|
||||||
self.filterMu.RLock()
|
self.filterMu.RLock()
|
||||||
for _, filter := range self.filters {
|
for _, filter := range self.filters {
|
||||||
if filter.MessageCallback != nil {
|
if filter.MessageCallback != nil {
|
||||||
msgs := filter.FilterMessages(messages)
|
msgs := filter.FilterMessages(event)
|
||||||
if len(msgs) > 0 {
|
if len(msgs) > 0 {
|
||||||
filter.MessageCallback(msgs)
|
filter.MessageCallback(msgs)
|
||||||
}
|
}
|
||||||
@ -659,7 +640,6 @@ out:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
func bootstrapDb(db ethutil.Database) {
|
func bootstrapDb(db ethutil.Database) {
|
||||||
d, _ := db.Get([]byte("ProtocolVersion"))
|
d, _ := db.Get([]byte("ProtocolVersion"))
|
||||||
|
@ -6,8 +6,8 @@ import (
|
|||||||
|
|
||||||
"github.com/ethereum/eth-go/ethchain"
|
"github.com/ethereum/eth-go/ethchain"
|
||||||
"github.com/ethereum/eth-go/ethlog"
|
"github.com/ethereum/eth-go/ethlog"
|
||||||
"github.com/ethereum/eth-go/ethreact"
|
|
||||||
"github.com/ethereum/eth-go/ethwire"
|
"github.com/ethereum/eth-go/ethwire"
|
||||||
|
"github.com/ethereum/eth-go/event"
|
||||||
)
|
)
|
||||||
|
|
||||||
var logger = ethlog.NewLogger("MINER")
|
var logger = ethlog.NewLogger("MINER")
|
||||||
@ -16,17 +16,27 @@ type Miner struct {
|
|||||||
pow ethchain.PoW
|
pow ethchain.PoW
|
||||||
ethereum ethchain.EthManager
|
ethereum ethchain.EthManager
|
||||||
coinbase []byte
|
coinbase []byte
|
||||||
reactChan chan ethreact.Event
|
|
||||||
txs ethchain.Transactions
|
txs ethchain.Transactions
|
||||||
uncles []*ethchain.Block
|
uncles []*ethchain.Block
|
||||||
block *ethchain.Block
|
block *ethchain.Block
|
||||||
powChan chan []byte
|
|
||||||
powQuitChan chan ethreact.Event
|
events event.Subscription
|
||||||
quitChan chan chan error
|
powQuitChan chan struct{}
|
||||||
|
powDone chan struct{}
|
||||||
|
|
||||||
turbo bool
|
turbo bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
Started = iota
|
||||||
|
Stopped
|
||||||
|
)
|
||||||
|
|
||||||
|
type Event struct {
|
||||||
|
Type int // Started || Stopped
|
||||||
|
Miner *Miner
|
||||||
|
}
|
||||||
|
|
||||||
func (self *Miner) GetPow() ethchain.PoW {
|
func (self *Miner) GetPow() ethchain.PoW {
|
||||||
return self.pow
|
return self.pow
|
||||||
}
|
}
|
||||||
@ -48,46 +58,42 @@ func (self *Miner) ToggleTurbo() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (miner *Miner) Start() {
|
func (miner *Miner) Start() {
|
||||||
miner.reactChan = make(chan ethreact.Event, 1) // This is the channel that receives 'updates' when ever a new transaction or block comes in
|
|
||||||
miner.powChan = make(chan []byte, 1) // This is the channel that receives valid sha hashes for a given block
|
|
||||||
miner.powQuitChan = make(chan ethreact.Event, 1) // This is the channel that can exit the miner thread
|
|
||||||
miner.quitChan = make(chan chan error, 1)
|
|
||||||
|
|
||||||
// Insert initial TXs in our little miner 'pool'
|
// Insert initial TXs in our little miner 'pool'
|
||||||
miner.txs = miner.ethereum.TxPool().Flush()
|
miner.txs = miner.ethereum.TxPool().Flush()
|
||||||
miner.block = miner.ethereum.BlockChain().NewBlock(miner.coinbase)
|
miner.block = miner.ethereum.BlockChain().NewBlock(miner.coinbase)
|
||||||
|
|
||||||
|
mux := miner.ethereum.EventMux()
|
||||||
|
miner.events = mux.Subscribe(ethchain.NewBlockEvent{}, ethchain.TxEvent{})
|
||||||
|
|
||||||
// Prepare inital block
|
// Prepare inital block
|
||||||
//miner.ethereum.StateManager().Prepare(miner.block.State(), miner.block.State())
|
//miner.ethereum.StateManager().Prepare(miner.block.State(), miner.block.State())
|
||||||
go miner.listener()
|
go miner.listener()
|
||||||
|
|
||||||
reactor := miner.ethereum.Reactor()
|
|
||||||
reactor.Subscribe("newBlock", miner.reactChan)
|
|
||||||
reactor.Subscribe("newTx:pre", miner.reactChan)
|
|
||||||
|
|
||||||
// We need the quit chan to be a Reactor event.
|
|
||||||
// The POW search method is actually blocking and if we don't
|
|
||||||
// listen to the reactor events inside of the pow itself
|
|
||||||
// The miner overseer will never get the reactor events themselves
|
|
||||||
// Only after the miner will find the sha
|
|
||||||
reactor.Subscribe("newBlock", miner.powQuitChan)
|
|
||||||
reactor.Subscribe("newTx:pre", miner.powQuitChan)
|
|
||||||
|
|
||||||
logger.Infoln("Started")
|
logger.Infoln("Started")
|
||||||
|
mux.Post(Event{Started, miner})
|
||||||
|
}
|
||||||
|
|
||||||
reactor.Post("miner:start", miner)
|
func (miner *Miner) Stop() {
|
||||||
|
logger.Infoln("Stopping...")
|
||||||
|
miner.events.Unsubscribe()
|
||||||
|
miner.ethereum.EventMux().Post(Event{Stopped, miner})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (miner *Miner) listener() {
|
func (miner *Miner) listener() {
|
||||||
for {
|
for {
|
||||||
select {
|
miner.startMining()
|
||||||
case status := <-miner.quitChan:
|
|
||||||
logger.Infoln("Stopped")
|
|
||||||
status <- nil
|
|
||||||
return
|
|
||||||
case chanMessage := <-miner.reactChan:
|
|
||||||
|
|
||||||
if block, ok := chanMessage.Resource.(*ethchain.Block); ok {
|
select {
|
||||||
|
case event, isopen := <-miner.events.Chan():
|
||||||
|
miner.stopMining()
|
||||||
|
if !isopen {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
switch event := event.(type) {
|
||||||
|
case ethchain.NewBlockEvent:
|
||||||
|
block := event.Block
|
||||||
//logger.Infoln("Got new block via Reactor")
|
//logger.Infoln("Got new block via Reactor")
|
||||||
if bytes.Compare(miner.ethereum.BlockChain().CurrentBlock.Hash(), block.Hash()) == 0 {
|
if bytes.Compare(miner.ethereum.BlockChain().CurrentBlock.Hash(), block.Hash()) == 0 {
|
||||||
// TODO: Perhaps continue mining to get some uncle rewards
|
// TODO: Perhaps continue mining to get some uncle rewards
|
||||||
@ -117,49 +123,44 @@ func (miner *Miner) listener() {
|
|||||||
miner.uncles = append(miner.uncles, block)
|
miner.uncles = append(miner.uncles, block)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if tx, ok := chanMessage.Resource.(*ethchain.Transaction); ok {
|
case ethchain.TxEvent:
|
||||||
|
if event.Type == ethchain.TxPre {
|
||||||
found := false
|
found := false
|
||||||
for _, ctx := range miner.txs {
|
for _, ctx := range miner.txs {
|
||||||
if found = bytes.Compare(ctx.Hash(), tx.Hash()) == 0; found {
|
if found = bytes.Compare(ctx.Hash(), event.Tx.Hash()) == 0; found {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
if found == false {
|
if found == false {
|
||||||
// Undo all previous commits
|
// Undo all previous commits
|
||||||
miner.block.Undo()
|
miner.block.Undo()
|
||||||
// Apply new transactions
|
// Apply new transactions
|
||||||
miner.txs = append(miner.txs, tx)
|
miner.txs = append(miner.txs, event.Tx)
|
||||||
}
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
miner.mineNewBlock()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (miner *Miner) Stop() {
|
case <-miner.powDone:
|
||||||
logger.Infoln("Stopping...")
|
// next iteration will start mining again
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
miner.powQuitChan <- ethreact.Event{}
|
func (miner *Miner) startMining() {
|
||||||
|
if miner.powDone == nil {
|
||||||
|
miner.powDone = make(chan struct{})
|
||||||
|
}
|
||||||
|
miner.powQuitChan = make(chan struct{})
|
||||||
|
go miner.mineNewBlock()
|
||||||
|
}
|
||||||
|
|
||||||
status := make(chan error)
|
func (miner *Miner) stopMining() {
|
||||||
miner.quitChan <- status
|
close(miner.powQuitChan)
|
||||||
<-status
|
<-miner.powDone
|
||||||
|
|
||||||
reactor := miner.ethereum.Reactor()
|
|
||||||
reactor.Unsubscribe("newBlock", miner.powQuitChan)
|
|
||||||
reactor.Unsubscribe("newTx:pre", miner.powQuitChan)
|
|
||||||
reactor.Unsubscribe("newBlock", miner.reactChan)
|
|
||||||
reactor.Unsubscribe("newTx:pre", miner.reactChan)
|
|
||||||
|
|
||||||
reactor.Post("miner:stop", miner)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Miner) mineNewBlock() {
|
func (self *Miner) mineNewBlock() {
|
||||||
|
|
||||||
stateManager := self.ethereum.StateManager()
|
stateManager := self.ethereum.StateManager()
|
||||||
|
|
||||||
self.block = self.ethereum.BlockChain().NewBlock(self.coinbase)
|
self.block = self.ethereum.BlockChain().NewBlock(self.coinbase)
|
||||||
@ -195,8 +196,9 @@ func (self *Miner) mineNewBlock() {
|
|||||||
logger.Infof("Mining on block. Includes %v transactions", len(self.txs))
|
logger.Infof("Mining on block. Includes %v transactions", len(self.txs))
|
||||||
|
|
||||||
// Find a valid nonce
|
// Find a valid nonce
|
||||||
self.block.Nonce = self.pow.Search(self.block, self.powQuitChan)
|
nonce := self.pow.Search(self.block, self.powQuitChan)
|
||||||
if self.block.Nonce != nil {
|
if nonce != nil {
|
||||||
|
self.block.Nonce = nonce
|
||||||
err := self.ethereum.StateManager().Process(self.block, false)
|
err := self.ethereum.StateManager().Process(self.block, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Infoln(err)
|
logger.Infoln(err)
|
||||||
@ -208,4 +210,5 @@ func (self *Miner) mineNewBlock() {
|
|||||||
self.txs = self.ethereum.TxPool().CurrentTransactions()
|
self.txs = self.ethereum.TxPool().CurrentTransactions()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
self.powDone <- struct{}{}
|
||||||
}
|
}
|
||||||
|
11
events.go
Normal file
11
events.go
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
package eth
|
||||||
|
|
||||||
|
import "container/list"
|
||||||
|
|
||||||
|
type PeerListEvent struct {
|
||||||
|
Peers *list.List
|
||||||
|
}
|
||||||
|
|
||||||
|
type ChainSyncEvent struct {
|
||||||
|
InSync bool
|
||||||
|
}
|
2
peer.go
2
peer.go
@ -802,7 +802,7 @@ func (p *Peer) handleHandshake(msg *ethwire.Msg) {
|
|||||||
p.versionKnown = true
|
p.versionKnown = true
|
||||||
|
|
||||||
p.ethereum.PushPeer(p)
|
p.ethereum.PushPeer(p)
|
||||||
p.ethereum.reactor.Post("peerList", p.ethereum.Peers())
|
p.ethereum.eventMux.Post(PeerListEvent{p.ethereum.Peers()})
|
||||||
|
|
||||||
p.protocolCaps = caps
|
p.protocolCaps = caps
|
||||||
capsIt := caps.NewIterator()
|
capsIt := caps.NewIterator()
|
||||||
|
Loading…
Reference in New Issue
Block a user