diff --git a/consensus/ethash/consensus.go b/consensus/ethash/consensus.go
index fb9a396ae4a7465a43d08eda58808f8db611092b..4d909146f2bac4236e098b37ed85925091f29a43 100644
--- a/consensus/ethash/consensus.go
+++ b/consensus/ethash/consensus.go
@@ -191,6 +191,9 @@ func (ethash *Ethash) VerifyUncles(chain consensus.ChainReader, block *types.Blo
 	if len(block.Uncles()) > maxUncles {
 		return errTooManyUncles
 	}
+	if len(block.Uncles()) == 0 {
+		return nil
+	}
 	// Gather the set of past uncles and ancestors
 	uncles, ancestors := mapset.NewSet(), make(map[common.Hash]*types.Header)
 
diff --git a/core/types/block.go b/core/types/block.go
index d611885f1ac41f6246b7ffa354f4a8730dd09a2b..f754c3c4870466ba15082252d5c8223bf1f75202 100644
--- a/core/types/block.go
+++ b/core/types/block.go
@@ -34,7 +34,7 @@ import (
 
 var (
 	EmptyRootHash  = DeriveSha(Transactions{})
-	EmptyUncleHash = CalcUncleHash(nil)
+	EmptyUncleHash = rlpHash([]*Header(nil))
 )
 
 // A BlockNonce is a 64-bit hash which proves (combined with the
@@ -324,6 +324,9 @@ func (c *writeCounter) Write(b []byte) (int, error) {
 }
 
 func CalcUncleHash(uncles []*Header) common.Hash {
+	if len(uncles) == 0 {
+		return EmptyUncleHash
+	}
 	return rlpHash(uncles)
 }
 
diff --git a/core/types/block_test.go b/core/types/block_test.go
index 2576f2fbc802e5c91e8a14f976fcc61f8fdb4378..bdd0b657170b005f5554bd8a47edc8feb7da291d 100644
--- a/core/types/block_test.go
+++ b/core/types/block_test.go
@@ -68,3 +68,19 @@ func TestBlockEncoding(t *testing.T) {
 		t.Errorf("encoded block mismatch:\ngot:  %x\nwant: %x", ourBlockEnc, blockEnc)
 	}
 }
+
+func TestUncleHash(t *testing.T) {
+	uncles := make([]*Header, 0)
+	h := CalcUncleHash(uncles)
+	exp := common.HexToHash("1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347")
+	if h != exp {
+		t.Fatalf("empty uncle hash is wrong, got %x != %x", h, exp)
+	}
+}
+func BenchmarkUncleHash(b *testing.B) {
+	uncles := make([]*Header, 0)
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		CalcUncleHash(uncles)
+	}
+}