浏览代码

eth: accept transactions when starting CPU mining (#13882)

Péter Szilágyi 8 年之前
父节点
当前提交
bfe5eb7f8c
共有 6 个文件被更改,包括 18 次插入10 次删除
  1. 1 1
      cmd/geth/main.go
  2. 2 2
      eth/api.go
  3. 9 1
      eth/backend.go
  4. 4 4
      eth/handler.go
  5. 1 1
      eth/protocol_test.go
  6. 1 1
      eth/sync.go

+ 1 - 1
cmd/geth/main.go

@@ -301,7 +301,7 @@ func startNode(ctx *cli.Context, stack *node.Node) {
 				th.SetThreads(threads)
 				th.SetThreads(threads)
 			}
 			}
 		}
 		}
-		if err := ethereum.StartMining(); err != nil {
+		if err := ethereum.StartMining(true); err != nil {
 			utils.Fatalf("Failed to start mining: %v", err)
 			utils.Fatalf("Failed to start mining: %v", err)
 		}
 		}
 	}
 	}

+ 2 - 2
eth/api.go

@@ -103,7 +103,7 @@ func (api *PublicMinerAPI) SubmitWork(nonce types.BlockNonce, solution, digest c
 // result[2], 32 bytes hex encoded boundary condition ("target"), 2^256/difficulty
 // result[2], 32 bytes hex encoded boundary condition ("target"), 2^256/difficulty
 func (api *PublicMinerAPI) GetWork() ([3]string, error) {
 func (api *PublicMinerAPI) GetWork() ([3]string, error) {
 	if !api.e.IsMining() {
 	if !api.e.IsMining() {
-		if err := api.e.StartMining(); err != nil {
+		if err := api.e.StartMining(false); err != nil {
 			return [3]string{}, err
 			return [3]string{}, err
 		}
 		}
 	}
 	}
@@ -153,7 +153,7 @@ func (api *PrivateMinerAPI) Start(threads *int) error {
 	}
 	}
 	// Start the miner and return
 	// Start the miner and return
 	if !api.e.IsMining() {
 	if !api.e.IsMining() {
-		return api.e.StartMining()
+		return api.e.StartMining(true)
 	}
 	}
 	return nil
 	return nil
 }
 }

+ 9 - 1
eth/backend.go

@@ -22,6 +22,7 @@ import (
 	"math/big"
 	"math/big"
 	"regexp"
 	"regexp"
 	"sync"
 	"sync"
+	"sync/atomic"
 
 
 	"github.com/ethereum/go-ethereum/accounts"
 	"github.com/ethereum/go-ethereum/accounts"
 	"github.com/ethereum/go-ethereum/common"
 	"github.com/ethereum/go-ethereum/common"
@@ -326,12 +327,19 @@ func (self *Ethereum) SetEtherbase(etherbase common.Address) {
 	self.miner.SetEtherbase(etherbase)
 	self.miner.SetEtherbase(etherbase)
 }
 }
 
 
-func (s *Ethereum) StartMining() error {
+func (s *Ethereum) StartMining(local bool) error {
 	eb, err := s.Etherbase()
 	eb, err := s.Etherbase()
 	if err != nil {
 	if err != nil {
 		log.Error("Cannot start mining without etherbase", "err", err)
 		log.Error("Cannot start mining without etherbase", "err", err)
 		return fmt.Errorf("etherbase missing: %v", err)
 		return fmt.Errorf("etherbase missing: %v", err)
 	}
 	}
+	if local {
+		// If local (CPU) mining is started, we can disable the transaction rejection
+		// mechanism introduced to speed sync times. CPU mining on mainnet is ludicrous
+		// so noone will ever hit this path, whereas marking sync done on CPU mining
+		// will ensure that private networks work in single miner mode too.
+		atomic.StoreUint32(&s.protocolManager.acceptTxs, 1)
+	}
 	go s.miner.Start(eb)
 	go s.miner.Start(eb)
 	return nil
 	return nil
 }
 }

+ 4 - 4
eth/handler.go

@@ -62,8 +62,8 @@ func errResp(code errCode, format string, v ...interface{}) error {
 type ProtocolManager struct {
 type ProtocolManager struct {
 	networkId int
 	networkId int
 
 
-	fastSync uint32 // Flag whether fast sync is enabled (gets disabled if we already have blocks)
-	synced   uint32 // Flag whether we're considered synchronised (enables transaction processing)
+	fastSync  uint32 // Flag whether fast sync is enabled (gets disabled if we already have blocks)
+	acceptTxs uint32 // Flag whether we're considered synchronised (enables transaction processing)
 
 
 	txpool      txPool
 	txpool      txPool
 	blockchain  *core.BlockChain
 	blockchain  *core.BlockChain
@@ -171,7 +171,7 @@ func NewProtocolManager(config *params.ChainConfig, fastSync bool, networkId int
 		return blockchain.CurrentBlock().NumberU64()
 		return blockchain.CurrentBlock().NumberU64()
 	}
 	}
 	inserter := func(blocks types.Blocks) (int, error) {
 	inserter := func(blocks types.Blocks) (int, error) {
-		atomic.StoreUint32(&manager.synced, 1) // Mark initial sync done on any fetcher import
+		atomic.StoreUint32(&manager.acceptTxs, 1) // Mark initial sync done on any fetcher import
 		return manager.blockchain.InsertChain(blocks)
 		return manager.blockchain.InsertChain(blocks)
 	}
 	}
 	manager.fetcher = fetcher.New(blockchain.GetBlockByHash, validator, manager.BroadcastBlock, heighter, inserter, manager.removePeer)
 	manager.fetcher = fetcher.New(blockchain.GetBlockByHash, validator, manager.BroadcastBlock, heighter, inserter, manager.removePeer)
@@ -643,7 +643,7 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
 
 
 	case msg.Code == TxMsg:
 	case msg.Code == TxMsg:
 		// Transactions arrived, make sure we have a valid and fresh chain to handle them
 		// Transactions arrived, make sure we have a valid and fresh chain to handle them
-		if atomic.LoadUint32(&pm.synced) == 0 {
+		if atomic.LoadUint32(&pm.acceptTxs) == 0 {
 			break
 			break
 		}
 		}
 		// Transactions can be processed, parse all of them and deliver to the pool
 		// Transactions can be processed, parse all of them and deliver to the pool

+ 1 - 1
eth/protocol_test.go

@@ -94,7 +94,7 @@ func TestRecvTransactions63(t *testing.T) { testRecvTransactions(t, 63) }
 func testRecvTransactions(t *testing.T, protocol int) {
 func testRecvTransactions(t *testing.T, protocol int) {
 	txAdded := make(chan []*types.Transaction)
 	txAdded := make(chan []*types.Transaction)
 	pm := newTestProtocolManagerMust(t, false, 0, nil, txAdded)
 	pm := newTestProtocolManagerMust(t, false, 0, nil, txAdded)
-	pm.synced = 1 // mark synced to accept transactions
+	pm.acceptTxs = 1 // mark synced to accept transactions
 	p, _ := newTestPeer("peer", protocol, pm, true)
 	p, _ := newTestPeer("peer", protocol, pm, true)
 	defer pm.Stop()
 	defer pm.Stop()
 	defer p.close()
 	defer p.close()

+ 1 - 1
eth/sync.go

@@ -188,7 +188,7 @@ func (pm *ProtocolManager) synchronise(peer *peer) {
 	if err := pm.downloader.Synchronise(peer.id, pHead, pTd, mode); err != nil {
 	if err := pm.downloader.Synchronise(peer.id, pHead, pTd, mode); err != nil {
 		return
 		return
 	}
 	}
-	atomic.StoreUint32(&pm.synced, 1) // Mark initial sync done
+	atomic.StoreUint32(&pm.acceptTxs, 1) // Mark initial sync done
 	if head := pm.blockchain.CurrentBlock(); head.NumberU64() > 0 {
 	if head := pm.blockchain.CurrentBlock(); head.NumberU64() > 0 {
 		// We've completed a sync cycle, notify all peers of new state. This path is
 		// We've completed a sync cycle, notify all peers of new state. This path is
 		// essential in star-topology networks where a gateway node needs to notify
 		// essential in star-topology networks where a gateway node needs to notify