|
|
@ -3,6 +3,7 @@ package core |
|
|
|
import ( |
|
|
|
import ( |
|
|
|
"fmt" |
|
|
|
"fmt" |
|
|
|
"math/big" |
|
|
|
"math/big" |
|
|
|
|
|
|
|
"math/rand" |
|
|
|
"os" |
|
|
|
"os" |
|
|
|
"path/filepath" |
|
|
|
"path/filepath" |
|
|
|
"runtime" |
|
|
|
"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) { |
|
|
|
|
|
|
|
} |
|
|
|