소스 검색

core, miner: added queued write to WriteBlock

This fixes an issue with the lru cache not being available when calling
WriteBlock. WriteBlock previously always assumed to be called from the
InsertChain where the lru cache was always created prior to calling
WriteBlock. When being called from the worker this could lead in to a
nil pointer exception being thrown and causing database corruption.
Jeffrey Wilcke 10 년 전
부모
커밋
d8fe64acaa
2개의 변경된 파일19개의 추가작업 그리고 16개의 파일을 삭제
  1. 18 15
      core/chain_manager.go
  2. 1 1
      miner/worker.go

+ 18 - 15
core/chain_manager.go

@@ -364,14 +364,12 @@ func (bc *ChainManager) insert(block *types.Block) {
 func (bc *ChainManager) write(block *types.Block) {
 	tstart := time.Now()
 
-	go func() {
-		enc, _ := rlp.EncodeToBytes((*types.StorageBlock)(block))
-		key := append(blockHashPre, block.Hash().Bytes()...)
-		err := bc.blockDb.Put(key, enc)
-		if err != nil {
-			glog.Fatal("db write fail:", err)
-		}
-	}()
+	enc, _ := rlp.EncodeToBytes((*types.StorageBlock)(block))
+	key := append(blockHashPre, block.Hash().Bytes()...)
+	err := bc.blockDb.Put(key, enc)
+	if err != nil {
+		glog.Fatal("db write fail:", err)
+	}
 
 	if glog.V(logger.Debug) {
 		glog.Infof("wrote block #%v %s. Took %v\n", block.Number(), common.PP(block.Hash().Bytes()), time.Since(tstart))
@@ -555,7 +553,8 @@ const (
 	sideStatTy
 )
 
-func (self *ChainManager) WriteBlock(block *types.Block) (status writeStatus, err error) {
+// WriteBlock writes the block to the chain (or pending queue)
+func (self *ChainManager) WriteBlock(block *types.Block, queued bool) (status writeStatus, err error) {
 	self.wg.Add(1)
 	defer self.wg.Done()
 
@@ -587,11 +586,15 @@ func (self *ChainManager) WriteBlock(block *types.Block) (status writeStatus, er
 		status = sideStatTy
 	}
 
-	// Write block to database. Eventually we'll have to improve on this and throw away blocks that are
-	// not in the canonical chain.
-	self.mu.Lock()
-	self.enqueueForWrite(block)
-	self.mu.Unlock()
+	if queued {
+		// Write block to database. Eventually we'll have to improve on this and throw away blocks that are
+		// not in the canonical chain.
+		self.mu.Lock()
+		self.enqueueForWrite(block)
+		self.mu.Unlock()
+	} else {
+		self.write(block)
+	}
 	// Delete from future blocks
 	self.futureBlocks.Remove(block.Hash())
 
@@ -693,7 +696,7 @@ func (self *ChainManager) InsertChain(chain types.Blocks) (int, error) {
 		txcount += len(block.Transactions())
 
 		// write the block to the chain and get the status
-		status, err := self.WriteBlock(block)
+		status, err := self.WriteBlock(block, true)
 		if err != nil {
 			return i, err
 		}

+ 1 - 1
miner/worker.go

@@ -233,7 +233,7 @@ func (self *worker) wait() {
 				continue
 			}
 
-			_, err := self.chain.WriteBlock(block)
+			_, err := self.chain.WriteBlock(block, false)
 			if err != nil {
 				glog.V(logger.Error).Infoln("error writing block to chain", err)
 				continue