Răsfoiți Sursa

core: return the index of the block that failed when inserting a chain

obscuren 10 ani în urmă
părinte
comite
735b029db9

+ 2 - 2
cmd/utils/cmd.go

@@ -172,7 +172,7 @@ func ImportChain(chainmgr *core.ChainManager, fn string) error {
 		n++
 
 		if n == batchSize {
-			if err := chainmgr.InsertChain(blocks); err != nil {
+			if _, err := chainmgr.InsertChain(blocks); err != nil {
 				return fmt.Errorf("invalid block %v", err)
 			}
 			n = 0
@@ -181,7 +181,7 @@ func ImportChain(chainmgr *core.ChainManager, fn string) error {
 	}
 
 	if n > 0 {
-		if err := chainmgr.InsertChain(blocks[:n]); err != nil {
+		if _, err := chainmgr.InsertChain(blocks[:n]); err != nil {
 			return fmt.Errorf("invalid block %v", err)
 		}
 	}

+ 1 - 1
core/chain_makers.go

@@ -141,6 +141,6 @@ func newCanonical(n int, db common.Database) (*BlockProcessor, error) {
 		return bman, nil
 	}
 	lchain := makeChain(bman, parent, n, db, CanonicalSeed)
-	err := bman.bc.InsertChain(lchain)
+	_, err := bman.bc.InsertChain(lchain)
 	return bman, err
 }

+ 5 - 3
core/chain_manager.go

@@ -497,7 +497,9 @@ func (self *ChainManager) procFutureBlocks() {
 	self.InsertChain(blocks)
 }
 
-func (self *ChainManager) InsertChain(chain types.Blocks) error {
+// InsertChain will attempt to insert the given chain in to the canonical chain or, otherwise, create a fork. It an error is returned
+// it will return the index number of the failing block as well an error describing what went wrong (for possible errors see core/errors.go).
+func (self *ChainManager) InsertChain(chain types.Blocks) (int, error) {
 	// A queued approach to delivering events. This is generally faster than direct delivery and requires much less mutex acquiring.
 	var (
 		queue      = make([]interface{}, len(chain))
@@ -540,7 +542,7 @@ func (self *ChainManager) InsertChain(chain types.Blocks) error {
 			glog.V(logger.Error).Infoln(err)
 			glog.V(logger.Debug).Infoln(block)
 
-			return err
+			return i, err
 		}
 
 		block.Td = new(big.Int).Set(CalculateTD(block, self.GetBlock(block.ParentHash())))
@@ -613,7 +615,7 @@ func (self *ChainManager) InsertChain(chain types.Blocks) error {
 
 	go self.eventMux.Post(queueEvent)
 
-	return nil
+	return 0, nil
 }
 
 // diff takes two blocks, an old chain and a new chain and will reconstruct the blocks and inserts them

+ 4 - 5
eth/downloader/downloader.go

@@ -37,7 +37,7 @@ var (
 )
 
 type hashCheckFn func(common.Hash) bool
-type chainInsertFn func(types.Blocks) error
+type chainInsertFn func(types.Blocks) (int, error)
 type hashIterFn func() (common.Hash, error)
 
 type blockPack struct {
@@ -432,12 +432,11 @@ func (d *Downloader) process(peer *peer) error {
 		// TODO check for parent error. When there's a parent error we should stop
 		// processing and start requesting the `block.hash` so that it's parent and
 		// grandparents can be requested and queued.
-		err = d.insertChain(blocks[:max])
+		var i int
+		i, err = d.insertChain(blocks[:max])
 		if err != nil && core.IsParentErr(err) {
-			glog.V(logger.Debug).Infoln("Aborting process due to missing parent.")
+			glog.V(logger.Debug).Infof("Aborting process due to missing parent (%d)\n", i)
 
-			// XXX this needs a lot of attention
-			blocks = nil
 			break
 		} else if err != nil {
 			// immediatly unregister the false peer but do not disconnect

+ 1 - 1
eth/handler.go

@@ -376,7 +376,7 @@ func (self *ProtocolManager) handleMsg(p *peer) error {
 		// if the parent exists we process the block and propagate to our peers
 		// if the parent does not exists we delegate to the downloader.
 		if self.chainman.HasBlock(request.Block.ParentHash()) {
-			if err := self.chainman.InsertChain(types.Blocks{request.Block}); err != nil {
+			if _, err := self.chainman.InsertChain(types.Blocks{request.Block}); err != nil {
 				// handle error
 				return nil
 			}

+ 1 - 1
miner/worker.go

@@ -184,7 +184,7 @@ func (self *worker) wait() {
 				continue
 			}
 
-			if err := self.chain.InsertChain(types.Blocks{block}); err == nil {
+			if _, err := self.chain.InsertChain(types.Blocks{block}); err == nil {
 				for _, uncle := range block.Uncles() {
 					delete(self.possibleUncles, uncle.Hash())
 				}

+ 1 - 1
tests/block_test_util.go

@@ -162,7 +162,7 @@ func (t *BlockTest) TryBlocksInsert(chainManager *core.ChainManager) error {
 			}
 		}
 		// RLP decoding worked, try to insert into chain:
-		err = chainManager.InsertChain(types.Blocks{cb})
+		_, err = chainManager.InsertChain(types.Blocks{cb})
 		if err != nil {
 			if b.BlockHeader == nil {
 				continue // OK - block is supposed to be invalid, continue with next block