core: fix the nonce check one more time
The block nonce verification was effectively disabled by a typo. This time, there is an actual test for it.
This commit is contained in:
		| @@ -551,12 +551,12 @@ func (self *ChainManager) InsertChain(chain types.Blocks) (int, error) { | ||||
| 		bstart := time.Now() | ||||
| 		// Wait for block i's nonce to be verified before processing | ||||
| 		// its state transition. | ||||
| 		for nonceChecked[i] { | ||||
| 		for !nonceChecked[i] { | ||||
| 			r := <-nonceDone | ||||
| 			nonceChecked[r.i] = true | ||||
| 			if !r.valid { | ||||
| 				block := chain[i] | ||||
| 				return i, ValidationError("Block (#%v / %x) nonce is invalid (= %x)", block.Number(), block.Hash(), block.Nonce) | ||||
| 				block := chain[r.i] | ||||
| 				return r.i, &BlockNonceErr{Hash: block.Hash(), Number: block.Number(), Nonce: block.Nonce()} | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
|   | ||||
| @@ -3,6 +3,7 @@ package core | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"math/big" | ||||
| 	"math/rand" | ||||
| 	"os" | ||||
| 	"path/filepath" | ||||
| 	"runtime" | ||||
| @@ -426,3 +427,55 @@ func TestReorgShortest(t *testing.T) { | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestInsertNonceError(t *testing.T) { | ||||
| 	for i := 1; i < 25 && !t.Failed(); i++ { | ||||
| 		db, _ := ethdb.NewMemDatabase() | ||||
| 		genesis := GenesisBlock(db) | ||||
| 		bc := chm(genesis, db) | ||||
| 		bc.processor = NewBlockProcessor(db, db, bc.pow, bc, bc.eventMux) | ||||
| 		blocks := makeChain(bc.processor.(*BlockProcessor), bc.currentBlock, i, db, 0) | ||||
|  | ||||
| 		fail := rand.Int() % len(blocks) | ||||
| 		failblock := blocks[fail] | ||||
| 		bc.pow = failpow{failblock.NumberU64()} | ||||
| 		n, err := bc.InsertChain(blocks) | ||||
|  | ||||
| 		// Check that the returned error indicates the nonce failure. | ||||
| 		if n != fail { | ||||
| 			t.Errorf("(i=%d) wrong failed block index: got %d, want %d", i, n, fail) | ||||
| 		} | ||||
| 		if !IsBlockNonceErr(err) { | ||||
| 			t.Fatalf("(i=%d) got %q, want a nonce error", i, err) | ||||
| 		} | ||||
| 		nerr := err.(*BlockNonceErr) | ||||
| 		if nerr.Number.Cmp(failblock.Number()) != 0 { | ||||
| 			t.Errorf("(i=%d) wrong block number in error, got %v, want %v", i, nerr.Number, failblock.Number()) | ||||
| 		} | ||||
| 		if nerr.Hash != failblock.Hash() { | ||||
| 			t.Errorf("(i=%d) wrong block hash in error, got %v, want %v", i, nerr.Hash, failblock.Hash()) | ||||
| 		} | ||||
|  | ||||
| 		// Check that all no blocks after the failing block have been inserted. | ||||
| 		for _, block := range blocks[fail:] { | ||||
| 			if bc.HasBlock(block.Hash()) { | ||||
| 				t.Errorf("(i=%d) invalid block %d present in chain", i, block.NumberU64()) | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // failpow returns false from Verify for a certain block number. | ||||
| type failpow struct{ num uint64 } | ||||
|  | ||||
| func (pow failpow) Search(pow.Block, <-chan struct{}) (nonce uint64, mixHash []byte) { | ||||
| 	return 0, nil | ||||
| } | ||||
| func (pow failpow) Verify(b pow.Block) bool { | ||||
| 	return b.NumberU64() != pow.num | ||||
| } | ||||
| func (pow failpow) GetHashrate() int64 { | ||||
| 	return 0 | ||||
| } | ||||
| func (pow failpow) Turbo(bool) { | ||||
| } | ||||
|   | ||||
| @@ -90,6 +90,23 @@ func IsNonceErr(err error) bool { | ||||
| 	return ok | ||||
| } | ||||
|  | ||||
| // BlockNonceErr indicates that a block's nonce is invalid. | ||||
| type BlockNonceErr struct { | ||||
| 	Number *big.Int | ||||
| 	Hash   common.Hash | ||||
| 	Nonce  uint64 | ||||
| } | ||||
|  | ||||
| func (err *BlockNonceErr) Error() string { | ||||
| 	return fmt.Sprintf("block %d (%v) nonce is invalid (got %d)", err.Number, err.Hash, err.Nonce) | ||||
| } | ||||
|  | ||||
| // IsBlockNonceErr returns true for invalid block nonce errors. | ||||
| func IsBlockNonceErr(err error) bool { | ||||
| 	_, ok := err.(*BlockNonceErr) | ||||
| 	return ok | ||||
| } | ||||
|  | ||||
| type InvalidTxErr struct { | ||||
| 	Message string | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user