aboutsummaryrefslogtreecommitdiffstats
path: root/consensus/ethash/sealer_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'consensus/ethash/sealer_test.go')
-rw-r--r--consensus/ethash/sealer_test.go94
1 files changed, 89 insertions, 5 deletions
diff --git a/consensus/ethash/sealer_test.go b/consensus/ethash/sealer_test.go
index d1b66f9cf..31d18b67c 100644
--- a/consensus/ethash/sealer_test.go
+++ b/consensus/ethash/sealer_test.go
@@ -41,14 +41,14 @@ func TestRemoteNotify(t *testing.T) {
go server.Serve(listener)
// Create the custom ethash engine
- ethash := NewTester([]string{"http://" + listener.Addr().String()})
+ ethash := NewTester([]string{"http://" + listener.Addr().String()}, false)
defer ethash.Close()
// Stream a work task and ensure the notification bubbles out
header := &types.Header{Number: big.NewInt(1), Difficulty: big.NewInt(100)}
block := types.NewBlockWithHeader(header)
- ethash.Seal(nil, block, nil)
+ ethash.Seal(nil, block, nil, nil)
select {
case work := <-sink:
if want := ethash.SealHash(header).Hex(); work[0] != want {
@@ -66,7 +66,7 @@ func TestRemoteNotify(t *testing.T) {
}
}
-// Tests that pushing work packages fast to the miner doesn't cause any daa race
+// Tests that pushing work packages fast to the miner doesn't cause any data race
// issues in the notifications.
func TestRemoteMultiNotify(t *testing.T) {
// Start a simple webserver to capture notifications
@@ -95,7 +95,7 @@ func TestRemoteMultiNotify(t *testing.T) {
go server.Serve(listener)
// Create the custom ethash engine
- ethash := NewTester([]string{"http://" + listener.Addr().String()})
+ ethash := NewTester([]string{"http://" + listener.Addr().String()}, false)
defer ethash.Close()
// Stream a lot of work task and ensure all the notifications bubble out
@@ -103,7 +103,7 @@ func TestRemoteMultiNotify(t *testing.T) {
header := &types.Header{Number: big.NewInt(int64(i)), Difficulty: big.NewInt(100)}
block := types.NewBlockWithHeader(header)
- ethash.Seal(nil, block, nil)
+ ethash.Seal(nil, block, nil, nil)
}
for i := 0; i < cap(sink); i++ {
select {
@@ -113,3 +113,87 @@ func TestRemoteMultiNotify(t *testing.T) {
}
}
}
+
+// Tests whether stale solutions are correctly processed.
+func TestStaleSubmission(t *testing.T) {
+ ethash := NewTester(nil, true)
+ defer ethash.Close()
+ api := &API{ethash}
+
+ fakeNonce, fakeDigest := types.BlockNonce{0x01, 0x02, 0x03}, common.HexToHash("deadbeef")
+
+ testcases := []struct {
+ headers []*types.Header
+ submitIndex int
+ submitRes bool
+ }{
+ // Case1: submit solution for the latest mining package
+ {
+ []*types.Header{
+ {ParentHash: common.BytesToHash([]byte{0xa}), Number: big.NewInt(1), Difficulty: big.NewInt(100000000)},
+ },
+ 0,
+ true,
+ },
+ // Case2: submit solution for the previous package but have same parent.
+ {
+ []*types.Header{
+ {ParentHash: common.BytesToHash([]byte{0xb}), Number: big.NewInt(2), Difficulty: big.NewInt(100000000)},
+ {ParentHash: common.BytesToHash([]byte{0xb}), Number: big.NewInt(2), Difficulty: big.NewInt(100000001)},
+ },
+ 0,
+ true,
+ },
+ // Case3: submit stale but acceptable solution
+ {
+ []*types.Header{
+ {ParentHash: common.BytesToHash([]byte{0xc}), Number: big.NewInt(3), Difficulty: big.NewInt(100000000)},
+ {ParentHash: common.BytesToHash([]byte{0xd}), Number: big.NewInt(9), Difficulty: big.NewInt(100000000)},
+ },
+ 0,
+ true,
+ },
+ // Case4: submit very old solution
+ {
+ []*types.Header{
+ {ParentHash: common.BytesToHash([]byte{0xe}), Number: big.NewInt(10), Difficulty: big.NewInt(100000000)},
+ {ParentHash: common.BytesToHash([]byte{0xf}), Number: big.NewInt(17), Difficulty: big.NewInt(100000000)},
+ },
+ 0,
+ false,
+ },
+ }
+ results := make(chan *types.Block, 16)
+
+ for id, c := range testcases {
+ for _, h := range c.headers {
+ ethash.Seal(nil, types.NewBlockWithHeader(h), results, nil)
+ }
+ if res := api.SubmitWork(fakeNonce, ethash.SealHash(c.headers[c.submitIndex]), fakeDigest); res != c.submitRes {
+ t.Errorf("case %d submit result mismatch, want %t, get %t", id+1, c.submitRes, res)
+ }
+ if !c.submitRes {
+ continue
+ }
+ select {
+ case res := <-results:
+ if res.Header().Nonce != fakeNonce {
+ t.Errorf("case %d block nonce mismatch, want %s, get %s", id+1, fakeNonce, res.Header().Nonce)
+ }
+ if res.Header().MixDigest != fakeDigest {
+ t.Errorf("case %d block digest mismatch, want %s, get %s", id+1, fakeDigest, res.Header().MixDigest)
+ }
+ if res.Header().Difficulty.Uint64() != c.headers[c.submitIndex].Difficulty.Uint64() {
+ t.Errorf("case %d block difficulty mismatch, want %d, get %d", id+1, c.headers[c.submitIndex].Difficulty, res.Header().Difficulty)
+ }
+ if res.Header().Number.Uint64() != c.headers[c.submitIndex].Number.Uint64() {
+ t.Errorf("case %d block number mismatch, want %d, get %d", id+1, c.headers[c.submitIndex].Number.Uint64(), res.Header().Number.Uint64())
+ }
+ if res.Header().ParentHash != c.headers[c.submitIndex].ParentHash {
+ t.Errorf("case %d block parent hash mismatch, want %s, get %s", id+1, c.headers[c.submitIndex].ParentHash.Hex(), res.Header().ParentHash.Hex())
+ }
+ case <-time.NewTimer(time.Second).C:
+ t.Errorf("case %d fetch ethash result timeout", id+1)
+ }
+ }
+}