Skip to content

Commit

Permalink
BEP-402: Complete Missing Fields in Block Header to Generate Signature
Browse files Browse the repository at this point in the history
  • Loading branch information
MatusKysel committed Jul 23, 2024
1 parent 442dc1b commit 515eed0
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 45 deletions.
18 changes: 18 additions & 0 deletions consensus/misc/eip4844.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"github.com/holiman/uint256"

"github.com/ledgerwatch/erigon-lib/chain"
libcommon "github.com/ledgerwatch/erigon-lib/common"
"github.com/ledgerwatch/erigon-lib/common/fixedgas"

"github.com/ledgerwatch/erigon/core/types"
Expand Down Expand Up @@ -89,6 +90,23 @@ func VerifyPresenceOfCancunHeaderFields(header *types.Header) error {
return nil
}

// VerifyPresenceOfCancunHeaderFields checks that the fields introduced in Cancun (EIP-4844, EIP-4788) are present.
func VerifyPresenceOfBohrHeaderFields(header *types.Header) error {
if header.BlobGasUsed == nil {
return fmt.Errorf("header is missing blobGasUsed")
}
if header.ExcessBlobGas == nil {
return fmt.Errorf("header is missing excessBlobGas")
}
if header.ParentBeaconBlockRoot != nil || *header.ParentBeaconBlockRoot != (libcommon.Hash{}) {
return fmt.Errorf("invalid parentBeaconRoot, have %#x, expected zero hash", header.ParentBeaconBlockRoot)
}
if header.WithdrawalsHash == nil || *header.WithdrawalsHash != types.EmptyRootHash {
return errors.New("header has wrong WithdrawalsHash")
}
return nil
}

// VerifyAbsenceOfCancunHeaderFields checks that the header doesn't have any fields added in Cancun (EIP-4844, EIP-4788).
func VerifyAbsenceOfCancunHeaderFields(header *types.Header) error {
if header.BlobGasUsed != nil {
Expand Down
38 changes: 35 additions & 3 deletions consensus/parlia/parlia.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"encoding/hex"
"errors"
"fmt"
"io"
"math/big"
"sort"
"strings"
Expand Down Expand Up @@ -565,8 +566,15 @@ func (p *Parlia) verifyHeader(chain consensus.ChainHeaderReader, header *types.H
return err
}
} else {
if err := misc.VerifyPresenceOfCancunHeaderFields(header); err != nil {
return err
bohr := chain.Config().IsBohr(header.Number.Uint64(), header.Time)
if bohr {
if err := misc.VerifyPresenceOfBohrHeaderFields(header); err != nil {
return err
}
} else {
if err := misc.VerifyPresenceOfCancunHeaderFields(header); err != nil {
return err
}
}
}

Expand Down Expand Up @@ -1244,12 +1252,36 @@ func (p *Parlia) Seal(chain consensus.ChainHeaderReader, block *types.Block, res
return nil
}

func encodeSigHeaderWithoutVoteAttestation(w io.Writer, header *types.Header, chainId *big.Int) {
err := rlp.Encode(w, []interface{}{
chainId,
header.ParentHash,
header.UncleHash,
header.Coinbase,
header.Root,
header.TxHash,
header.ReceiptHash,
header.Bloom,
header.Difficulty,
header.Number,
header.GasLimit,
header.GasUsed,
header.Time,
header.Extra[:extraVanity], // this will panic if extra is too short, should check before calling encodeSigHeaderWithoutVoteAttestation
header.MixDigest,
header.Nonce,
})
if err != nil {
panic("can't encode: " + err.Error())
}
}

// SealHash returns the hash of a block prior to it being sealed.
func (p *Parlia) SealHash(header *types.Header) (hash libcommon.Hash) {
hasher := cryptopool.NewLegacyKeccak256()
defer cryptopool.ReturnToPoolKeccak256(hasher)

types.EncodeSigHeaderWithoutVoteAttestation(hasher, header, p.chainConfig.ChainID)
encodeSigHeaderWithoutVoteAttestation(hasher, header, p.chainConfig.ChainID)
hasher.Sum(hash[:0])
return hash
}
Expand Down
2 changes: 1 addition & 1 deletion core/chain_makers.go
Original file line number Diff line number Diff line change
Expand Up @@ -616,7 +616,7 @@ func MakeEmptyHeader(parent *types.Header, chainConfig *chain.Config, timestamp
if chainConfig.Parlia != nil {
header.WithdrawalsHash = &types.EmptyRootHash
}
if chainConfig.Parlia == nil {
if chainConfig.Parlia == nil || chainConfig.IsBohr(header.Number.Uint64(), header.Time) {
header.ParentBeaconBlockRoot = new(libcommon.Hash)
}
}
Expand Down
85 changes: 44 additions & 41 deletions core/types/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -1565,48 +1565,51 @@ func SealHash(header *Header, chainId *big.Int) (hash libcommon.Hash) {
}

func EncodeSigHeader(w io.Writer, header *Header, chainId *big.Int) {
err := rlp.Encode(w, []interface{}{
chainId,
header.ParentHash,
header.UncleHash,
header.Coinbase,
header.Root,
header.TxHash,
header.ReceiptHash,
header.Bloom,
header.Difficulty,
header.Number,
header.GasLimit,
header.GasUsed,
header.Time,
header.Extra[:len(header.Extra)-extraSeal], // this will panic if extra is too short, should check before calling encodeSigHeader
header.MixDigest,
header.Nonce,
})
if err != nil {
panic("can't encode: " + err.Error())
var err error
if header.ParentBeaconBlockRoot != nil && *header.ParentBeaconBlockRoot == (libcommon.Hash{}) {
err = rlp.Encode(w, []interface{}{
chainId,
header.ParentHash,
header.UncleHash,
header.Coinbase,
header.Root,
header.TxHash,
header.ReceiptHash,
header.Bloom,
header.Difficulty,
header.Number,
header.GasLimit,
header.GasUsed,
header.Time,
header.Extra[:len(header.Extra)-extraSeal], // this will panic if extra is too short, should check before calling encodeSigHeader
header.MixDigest,
header.Nonce,
header.BaseFee,
header.WithdrawalsHash,
header.BlobGasUsed,
header.ExcessBlobGas,
header.ParentBeaconBlockRoot,
})
} else {
err = rlp.Encode(w, []interface{}{
chainId,
header.ParentHash,
header.UncleHash,
header.Coinbase,
header.Root,
header.TxHash,
header.ReceiptHash,
header.Bloom,
header.Difficulty,
header.Number,
header.GasLimit,
header.GasUsed,
header.Time,
header.Extra[:len(header.Extra)-extraSeal], // this will panic if extra is too short, should check before calling encodeSigHeader
header.MixDigest,
header.Nonce,
})
}
}

func EncodeSigHeaderWithoutVoteAttestation(w io.Writer, header *Header, chainId *big.Int) {
err := rlp.Encode(w, []interface{}{
chainId,
header.ParentHash,
header.UncleHash,
header.Coinbase,
header.Root,
header.TxHash,
header.ReceiptHash,
header.Bloom,
header.Difficulty,
header.Number,
header.GasLimit,
header.GasUsed,
header.Time,
header.Extra[:extraVanity], // this will panic if extra is too short, should check before calling encodeSigHeaderWithoutVoteAttestation
header.MixDigest,
header.Nonce,
})
if err != nil {
panic("can't encode: " + err.Error())
}
Expand Down

0 comments on commit 515eed0

Please sign in to comment.