From 0b0007ca82d9c021401f45f7ae4b4f707a9a3e45 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Mon, 11 Apr 2022 20:19:13 +0200 Subject: [PATCH 1/2] core/types: make "miner" optional in Header JSON (#24666) "miner" is not set for pending block responses in some cases. Fixes #24632 --- core/types/block.go | 2 +- core/types/gen_header_json.go | 9 ++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/core/types/block.go b/core/types/block.go index 60d109b5c07..6c553791089 100644 --- a/core/types/block.go +++ b/core/types/block.go @@ -76,7 +76,7 @@ func (n *BlockNonce) UnmarshalText(input []byte) error { type Header struct { ParentHash common.Hash `json:"parentHash" gencodec:"required"` UncleHash common.Hash `json:"sha3Uncles" gencodec:"required"` - Coinbase common.Address `json:"miner" gencodec:"required"` + Coinbase common.Address `json:"miner"` Root common.Hash `json:"stateRoot" gencodec:"required"` TxHash common.Hash `json:"transactionsRoot" gencodec:"required"` ReceiptHash common.Hash `json:"receiptsRoot" gencodec:"required"` diff --git a/core/types/gen_header_json.go b/core/types/gen_header_json.go index fbc5fae1db0..a7a65c018fb 100644 --- a/core/types/gen_header_json.go +++ b/core/types/gen_header_json.go @@ -18,7 +18,7 @@ func (h Header) MarshalJSON() ([]byte, error) { type Header struct { ParentHash common.Hash `json:"parentHash" gencodec:"required"` UncleHash common.Hash `json:"sha3Uncles" gencodec:"required"` - Coinbase common.Address `json:"miner" gencodec:"required"` + Coinbase common.Address `json:"miner"` Root common.Hash `json:"stateRoot" gencodec:"required"` TxHash common.Hash `json:"transactionsRoot" gencodec:"required"` ReceiptHash common.Hash `json:"receiptsRoot" gencodec:"required"` @@ -60,7 +60,7 @@ func (h *Header) UnmarshalJSON(input []byte) error { type Header struct { ParentHash *common.Hash `json:"parentHash" gencodec:"required"` UncleHash *common.Hash `json:"sha3Uncles" gencodec:"required"` - Coinbase *common.Address `json:"miner" gencodec:"required"` + Coinbase *common.Address `json:"miner"` Root *common.Hash `json:"stateRoot" gencodec:"required"` TxHash *common.Hash `json:"transactionsRoot" gencodec:"required"` ReceiptHash *common.Hash `json:"receiptsRoot" gencodec:"required"` @@ -87,10 +87,9 @@ func (h *Header) UnmarshalJSON(input []byte) error { return errors.New("missing required field 'sha3Uncles' for Header") } h.UncleHash = *dec.UncleHash - if dec.Coinbase == nil { - return errors.New("missing required field 'miner' for Header") + if dec.Coinbase != nil { + h.Coinbase = *dec.Coinbase } - h.Coinbase = *dec.Coinbase if dec.Root == nil { return errors.New("missing required field 'stateRoot' for Header") } From 9cc046defc429cfa285eceea089ac2b5d90ca58f Mon Sep 17 00:00:00 2001 From: yperbasis Date: Tue, 8 Nov 2022 10:45:18 +0100 Subject: [PATCH 2/2] Simplify Header.EncodeRLP --- core/types/block.go | 179 +++++----------------------------- core/types/gen_header_json.go | 4 +- rlp/encode.go | 22 +++++ 3 files changed, 51 insertions(+), 154 deletions(-) diff --git a/core/types/block.go b/core/types/block.go index 6c553791089..8a2fd31f5a2 100644 --- a/core/types/block.go +++ b/core/types/block.go @@ -89,27 +89,22 @@ type Header struct { Extra []byte `json:"extraData" gencodec:"required"` MixDigest common.Hash `json:"mixHash"` Nonce BlockNonce `json:"nonce"` - BaseFee *big.Int `json:"baseFeePerGas"` - AuRaStep uint64 - AuRaSeal []byte + // AuRa extensions (alternative to MixDigest & Nonce) + AuRaStep uint64 + AuRaSeal []byte + + BaseFee *big.Int `json:"baseFeePerGas"` // EIP-1559 + // The verkle proof is ignored in legacy headers Verkle bool - VerkleProof []byte `json:"verkleProof"` - VerkleKeyVals []verkle.KeyValuePair `json:"verkleKeyVals"` + VerkleProof []byte + VerkleKeyVals []verkle.KeyValuePair } -func (h Header) EncodingSize() int { +func (h *Header) EncodingSize() int { encodingSize := 33 /* ParentHash */ + 33 /* UncleHash */ + 21 /* Coinbase */ + 33 /* Root */ + 33 /* TxHash */ + 33 /* ReceiptHash */ + 259 /* Bloom */ - if len(h.AuRaSeal) != 0 { - encodingSize += 1 + rlp.IntLenExcludingHead(h.AuRaStep) + 1 + len(h.AuRaSeal) - if len(h.AuRaSeal) >= 56 { - encodingSize += (bits.Len(uint(len(h.AuRaSeal))) + 7) / 8 - } - } else { - encodingSize += 33 /* MixDigest */ + 9 /* BlockNonce */ - } encodingSize++ if h.Difficulty != nil { encodingSize += rlp.BigIntLenExcludingHead(h.Difficulty) @@ -138,48 +133,6 @@ func (h Header) EncodingSize() int { } encodingSize += len(h.Extra) } - // size of BaseFee - var baseFeeBitLen, baseFeeLen int - if h.BaseFee != nil { - encodingSize++ - baseFeeBitLen = h.BaseFee.BitLen() - if baseFeeBitLen >= 8 { - baseFeeLen = (baseFeeBitLen + 7) / 8 - } - encodingSize += baseFeeLen - } - - if h.Verkle { - // Encoding of Verkle Proof - encodingSize++ - switch len(h.VerkleProof) { - case 0: - case 1: - if h.VerkleProof[0] >= 128 { - encodingSize++ - } - default: - if len(h.VerkleProof) >= 56 { - encodingSize += (bits.Len(uint(len(h.VerkleProof))) + 7) / 8 - } - encodingSize += len(h.VerkleProof) - } - encodingSize++ - - var tmpBuffer bytes.Buffer - if err := rlp.Encode(&tmpBuffer, h.VerkleKeyVals); err != nil { - panic(err) - } - encodingSize += tmpBuffer.Len() - } - - return encodingSize -} - -func (h Header) EncodeRLP(w io.Writer) error { - // Precompute the size of the encoding - encodingSize := 33 /* ParentHash */ + 33 /* UncleHash */ + 21 /* Coinbase */ + 33 /* Root */ + 33 /* TxHash */ + - 33 /* ReceiptHash */ + 259 /* Bloom */ if len(h.AuRaSeal) != 0 { encodingSize += 1 + rlp.IntLenExcludingHead(h.AuRaStep) + 1 + len(h.AuRaSeal) @@ -189,6 +142,12 @@ func (h Header) EncodeRLP(w io.Writer) error { } else { encodingSize += 33 /* MixDigest */ + 9 /* BlockNonce */ } + + if h.BaseFee != nil { + encodingSize++ + encodingSize += rlp.BigIntLenExcludingHead(h.BaseFee) + } + if h.Verkle { // Encoding of Verkle Proof encodingSize++ @@ -208,62 +167,16 @@ func (h Header) EncodeRLP(w io.Writer) error { var tmpBuffer bytes.Buffer if err := rlp.Encode(&tmpBuffer, h.VerkleKeyVals); err != nil { - return nil + panic(err) } encodingSize += tmpBuffer.Len() } - encodingSize++ - var diffBitLen, diffLen int - if h.Difficulty != nil { - diffBitLen = h.Difficulty.BitLen() - if diffBitLen >= 8 { - diffLen = (diffBitLen + 7) / 8 - } - } - encodingSize += diffLen - - encodingSize++ - var numberBitLen, numberLen int - if h.Number != nil { - numberBitLen = h.Number.BitLen() - if numberBitLen >= 8 { - numberLen = (numberBitLen + 7) / 8 - } - } - encodingSize += numberLen - - encodingSize++ - encodingSize += rlp.IntLenExcludingHead(h.GasLimit) + return encodingSize +} - encodingSize++ - encodingSize += rlp.IntLenExcludingHead(h.GasUsed) - - encodingSize++ - encodingSize += rlp.IntLenExcludingHead(h.Time) - // size of Extra - encodingSize++ - switch len(h.Extra) { - case 0: - case 1: - if h.Extra[0] >= 128 { - encodingSize++ - } - default: - if len(h.Extra) >= 56 { - encodingSize += (bits.Len(uint(len(h.Extra))) + 7) / 8 - } - encodingSize += len(h.Extra) - } - var baseFeeBitLen, baseFeeLen int - if h.BaseFee != nil { - encodingSize++ - baseFeeBitLen = h.BaseFee.BitLen() - if baseFeeBitLen >= 8 { - baseFeeLen = (baseFeeBitLen + 7) / 8 - } - encodingSize += baseFeeLen - } +func (h *Header) EncodeRLP(w io.Writer) error { + encodingSize := h.EncodingSize() var b [33]byte // Prefix @@ -318,37 +231,11 @@ func (h Header) EncodeRLP(w io.Writer) error { if _, err := w.Write(h.Bloom.Bytes()); err != nil { return err } - if diffBitLen < 8 { - if diffBitLen > 0 { - b[0] = byte(h.Difficulty.Uint64()) - } else { - b[0] = 128 - } - if _, err := w.Write(b[:1]); err != nil { - return err - } - } else { - b[0] = 128 + byte(diffLen) - h.Difficulty.FillBytes(b[1 : 1+diffLen]) - if _, err := w.Write(b[:1+diffLen]); err != nil { - return err - } + if err := rlp.EncodeBigInt(h.Difficulty, w, b[:]); err != nil { + return err } - if numberBitLen < 8 { - if numberBitLen > 0 { - b[0] = byte(h.Number.Uint64()) - } else { - b[0] = 128 - } - if _, err := w.Write(b[:1]); err != nil { - return err - } - } else { - b[0] = 128 + byte(numberLen) - h.Number.FillBytes(b[1 : 1+numberLen]) - if _, err := w.Write(b[:1+numberLen]); err != nil { - return err - } + if err := rlp.EncodeBigInt(h.Number, w, b[:]); err != nil { + return err } if err := rlp.EncodeInt(h.GasLimit, w, b[:]); err != nil { return err @@ -388,21 +275,8 @@ func (h Header) EncodeRLP(w io.Writer) error { } if h.BaseFee != nil { - if baseFeeBitLen < 8 { - if baseFeeBitLen > 0 { - b[0] = byte(h.BaseFee.Uint64()) - } else { - b[0] = 128 - } - if _, err := w.Write(b[:1]); err != nil { - return err - } - } else { - b[0] = 128 + byte(baseFeeLen) - h.BaseFee.FillBytes(b[1 : 1+baseFeeLen]) - if _, err := w.Write(b[:1+baseFeeLen]); err != nil { - return err - } + if err := rlp.EncodeBigInt(h.BaseFee, w, b[:]); err != nil { + return err } } @@ -544,6 +418,7 @@ func (h *Header) DecodeRLP(s *rlp.Stream) error { } rlp.DecodeBytes(rawKv, h.VerkleKeyVals) } + if err := s.ListEnd(); err != nil { return fmt.Errorf("close header struct: %w", err) } diff --git a/core/types/gen_header_json.go b/core/types/gen_header_json.go index a7a65c018fb..9168a2bcd0a 100644 --- a/core/types/gen_header_json.go +++ b/core/types/gen_header_json.go @@ -31,7 +31,7 @@ func (h Header) MarshalJSON() ([]byte, error) { Extra hexutil.Bytes `json:"extraData" gencodec:"required"` MixDigest common.Hash `json:"mixHash"` Nonce BlockNonce `json:"nonce"` - BaseFee *hexutil.Big `json:"baseFeePerGas" rlp:"optional"` + BaseFee *hexutil.Big `json:"baseFeePerGas"` Hash common.Hash `json:"hash"` } var enc Header @@ -73,7 +73,7 @@ func (h *Header) UnmarshalJSON(input []byte) error { Extra *hexutil.Bytes `json:"extraData" gencodec:"required"` MixDigest *common.Hash `json:"mixHash"` Nonce *BlockNonce `json:"nonce"` - BaseFee *hexutil.Big `json:"baseFeePerGas" rlp:"optional"` + BaseFee *hexutil.Big `json:"baseFeePerGas"` } var dec Header if err := json.Unmarshal(input, &dec); err != nil { diff --git a/rlp/encode.go b/rlp/encode.go index 2eec8bcb253..afa5281d274 100644 --- a/rlp/encode.go +++ b/rlp/encode.go @@ -788,6 +788,28 @@ func EncodeInt(i uint64, w io.Writer, buffer []byte) error { return err } +func EncodeBigInt(i *big.Int, w io.Writer, buffer []byte) error { + bitLen := 0 // treat nil as 0 + if i != nil { + bitLen = i.BitLen() + } + if bitLen < 8 { + if bitLen > 0 { + buffer[0] = byte(i.Uint64()) + } else { + buffer[0] = 0x80 + } + _, err := w.Write(buffer[:1]) + return err + } + + size := (bitLen + 7) / 8 + buffer[0] = 0x80 + byte(size) + i.FillBytes(buffer[1 : 1+size]) + _, err := w.Write(buffer[:1+size]) + return err +} + func EncodeString(s []byte, w io.Writer, buffer []byte) error { switch len(s) { case 0: