From 2f275cb16d8b2eff26190ae5a7d3d9253797d453 Mon Sep 17 00:00:00 2001
From: Giulio Rebuffo <giulio.rebuffo@gmail.com>
Date: Sun, 14 Nov 2021 22:46:28 +0100
Subject: [PATCH] added random field to block type

---
 core/types/block.go      | 32 ++++++++++++++++++++++++++++++++
 core/types/block_test.go | 36 ++++++++++++++++++++++++++++++++++++
 2 files changed, 68 insertions(+)

diff --git a/core/types/block.go b/core/types/block.go
index 6a16ab4b60..dccd167b85 100644
--- a/core/types/block.go
+++ b/core/types/block.go
@@ -96,7 +96,9 @@ type Header struct {
 	MixDigest   common.Hash    `json:"mixHash"`
 	Nonce       BlockNonce     `json:"nonce"`
 	BaseFee     *big.Int       `json:"baseFeePerGas"`
+	Random      common.Hash    `json:"random"`
 	Eip1559     bool           // to avoid relying on BaseFee != nil for that
+	Eip3675     bool           // to avoid relying on Random != nil for that
 	Seal        []rlp.RawValue // AuRa POA network field
 	WithSeal    bool           // to avoid relying on Seal != nil for that
 }
@@ -243,6 +245,10 @@ func (h Header) EncodeRLP(w io.Writer) error {
 		encodingSize += baseFeeLen
 	}
 
+	if h.Eip3675 {
+		encodingSize += common.HashLength + 1
+	}
+
 	var b [33]byte
 	// Prefix
 	if err := EncodeStructSizePrefix(encodingSize, w, b[:]); err != nil {
@@ -401,6 +407,15 @@ func (h Header) EncodeRLP(w io.Writer) error {
 			}
 		}
 	}
+
+	if h.Eip3675 {
+		if _, err := w.Write([]byte{128 + common.HashLength}); err != nil {
+			return err
+		}
+		if _, err := w.Write(h.Random.Bytes()); err != nil {
+			return err
+		}
+	}
 	return nil
 }
 
@@ -529,6 +544,23 @@ func (h *Header) DecodeRLP(s *rlp.Stream) error {
 		}
 		h.Eip1559 = true
 		h.BaseFee = new(big.Int).SetBytes(b)
+
+		if b, err = s.Bytes(); err != nil {
+			if errors.Is(err, rlp.EOL) {
+				h.Random = common.Hash{}
+				h.Eip3675 = false
+				if err := s.ListEnd(); err != nil {
+					return fmt.Errorf("close header struct (no random): %w", err)
+				}
+				return nil
+			}
+			return fmt.Errorf("read BaseFee: %w", err)
+		}
+		if len(b) != common.HashLength {
+			return fmt.Errorf("wrong size for BaseFee: %d", len(b))
+		}
+		h.Eip3675 = true
+		h.Random = common.BytesToHash(b)
 	}
 	if err := s.ListEnd(); err != nil {
 		return fmt.Errorf("close header struct: %w", err)
diff --git a/core/types/block_test.go b/core/types/block_test.go
index fb817ec7fb..e8f01f1c4f 100644
--- a/core/types/block_test.go
+++ b/core/types/block_test.go
@@ -214,6 +214,42 @@ func TestUncleHash(t *testing.T) {
 	}
 }
 
+func TestRandom(t *testing.T) {
+
+	check := func(f string, got, want interface{}) {
+		if !reflect.DeepEqual(got, want) {
+			t.Errorf("%s mismatch: got %v, want %v", f, got, want)
+		}
+	}
+
+	header := Header{
+		Difficulty: math.BigPow(11, 11),
+		Coinbase:   common.HexToAddress("0x0000000000000000000000000000000000000001"),
+		GasLimit:   12345678,
+		GasUsed:    1476322,
+		Time:       9876543,
+		BaseFee:    common.Big1,
+		Random:     common.HexToHash("bd4472abb6659ebe3ee06ee4d7b72a00a9f4d001caca51342001075469aff498"),
+		Eip1559:    true,
+		Eip3675:    true,
+	}
+	var buf bytes.Buffer
+	err := header.EncodeRLP(&buf)
+	if err != nil {
+		t.Fatalf("err during encododing: %s", err.Error())
+	}
+	var decodedHeader Header
+	decodedHeader.DecodeRLP(rlp.NewStream(&buf, 0))
+
+	check("Difficulty", decodedHeader.Difficulty, math.BigPow(11, 11))
+	check("GasLimit", decodedHeader.GasLimit, uint64(12345678))
+	check("GasUsed", decodedHeader.GasUsed, uint64(1476322))
+	check("Coinbase", decodedHeader.Coinbase, common.HexToAddress("0x0000000000000000000000000000000000000001"))
+	check("BaseFee", decodedHeader.BaseFee, common.Big1)
+	check("Random", decodedHeader.Random, common.HexToHash("bd4472abb6659ebe3ee06ee4d7b72a00a9f4d001caca51342001075469aff498"))
+	check("Time", decodedHeader.Time, uint64(9876543))
+}
+
 var benchBuffer = bytes.NewBuffer(make([]byte, 0, 32000))
 
 func BenchmarkEncodeBlock(b *testing.B) {
-- 
GitLab