From d763b49ae3a7975157fed7886ef848ccd04e2e0e Mon Sep 17 00:00:00 2001
From: Martin Holst Swende <martin@swende.se>
Date: Mon, 8 Apr 2019 09:13:05 +0200
Subject: [PATCH] consensus,core: shortcut uncle validation

---
 consensus/ethash/consensus.go |  3 +++
 core/types/block.go           |  5 ++++-
 core/types/block_test.go      | 16 ++++++++++++++++
 3 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/consensus/ethash/consensus.go b/consensus/ethash/consensus.go
index fb9a396ae..4d909146f 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 d611885f1..f754c3c48 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 2576f2fbc..bdd0b6571 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)
+	}
+}
-- 
GitLab