consensus, core, eth/downloader, params: 4844 chain validation (#27382)

This commit is contained in:
Péter Szilágyi
2023-05-31 10:21:13 +03:00
committed by GitHub
parent cc2ab421e4
commit 1f9b69b36d
13 changed files with 208 additions and 65 deletions
+15 -2
View File
@@ -78,10 +78,23 @@ func (v *BlockValidator) ValidateBody(block *types.Block) error {
return fmt.Errorf("withdrawals root hash mismatch (header value %x, calculated %x)", *header.WithdrawalsHash, hash)
}
} else if block.Withdrawals() != nil {
// Withdrawals are not allowed prior to shanghai fork
// Withdrawals are not allowed prior to Shanghai fork
return errors.New("withdrawals present in block body")
}
// Blob transactions may be present after the Cancun fork.
var blobs int
for _, tx := range block.Transactions() {
blobs += len(tx.BlobHashes())
}
if header.DataGasUsed != nil {
if want := *header.DataGasUsed / params.BlobTxDataGasPerBlob; uint64(blobs) != want { // div because the header is surely good vs the body might be bloated
return fmt.Errorf("data gas used mismatch (header %v, calculated %v)", *header.DataGasUsed, blobs*params.BlobTxDataGasPerBlob)
}
} else {
if blobs > 0 {
return errors.New("data blobs present in block body")
}
}
if !v.bc.HasBlockAndState(block.ParentHash(), block.NumberU64()-1) {
if !v.bc.HasBlock(block.ParentHash(), block.NumberU64()-1) {
return consensus.ErrUnknownAncestor
+35 -12
View File
@@ -86,19 +86,24 @@ type Header struct {
WithdrawalsHash *common.Hash `json:"withdrawalsRoot" rlp:"optional"`
// ExcessDataGas was added by EIP-4844 and is ignored in legacy headers.
ExcessDataGas *big.Int `json:"excessDataGas" rlp:"optional"`
ExcessDataGas *uint64 `json:"excessDataGas" rlp:"optional"`
// DataGasUsed was added by EIP-4844 and is ignored in legacy headers.
DataGasUsed *uint64 `json:"dataGasUsed" rlp:"optional"`
}
// field type overrides for gencodec
type headerMarshaling struct {
Difficulty *hexutil.Big
Number *hexutil.Big
GasLimit hexutil.Uint64
GasUsed hexutil.Uint64
Time hexutil.Uint64
Extra hexutil.Bytes
BaseFee *hexutil.Big
Hash common.Hash `json:"hash"` // adds call to Hash() in MarshalJSON
Difficulty *hexutil.Big
Number *hexutil.Big
GasLimit hexutil.Uint64
GasUsed hexutil.Uint64
Time hexutil.Uint64
Extra hexutil.Bytes
BaseFee *hexutil.Big
Hash common.Hash `json:"hash"` // adds call to Hash() in MarshalJSON
ExcessDataGas *hexutil.Uint64
DataGasUsed *hexutil.Uint64
}
// Hash returns the block hash of the header, which is simply the keccak256 hash of its
@@ -146,10 +151,10 @@ func (h *Header) SanityCheck() error {
// EmptyBody returns true if there is no additional 'body' to complete the header
// that is: no transactions, no uncles and no withdrawals.
func (h *Header) EmptyBody() bool {
if h.WithdrawalsHash == nil {
return h.TxHash == EmptyTxsHash && h.UncleHash == EmptyUncleHash
if h.WithdrawalsHash != nil {
return h.TxHash == EmptyTxsHash && *h.WithdrawalsHash == EmptyWithdrawalsHash
}
return h.TxHash == EmptyTxsHash && h.UncleHash == EmptyUncleHash && *h.WithdrawalsHash == EmptyWithdrawalsHash
return h.TxHash == EmptyTxsHash && h.UncleHash == EmptyUncleHash
}
// EmptyReceipts returns true if there are no receipts for this header/block.
@@ -347,6 +352,24 @@ func (b *Block) Withdrawals() Withdrawals {
return b.withdrawals
}
func (b *Block) ExcessDataGas() *uint64 {
var excessDataGas *uint64
if b.header.ExcessDataGas != nil {
excessDataGas = new(uint64)
*excessDataGas = *b.header.ExcessDataGas
}
return excessDataGas
}
func (b *Block) DataGasUsed() *uint64 {
var dataGasUsed *uint64
if b.header.DataGasUsed != nil {
dataGasUsed = new(uint64)
*dataGasUsed = *b.header.DataGasUsed
}
return dataGasUsed
}
func (b *Block) Header() *Header { return CopyHeader(b.header) }
// Body returns the non-header content of the block.
+28 -22
View File
@@ -16,25 +16,26 @@ var _ = (*headerMarshaling)(nil)
// MarshalJSON marshals as JSON.
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"`
Root common.Hash `json:"stateRoot" gencodec:"required"`
TxHash common.Hash `json:"transactionsRoot" gencodec:"required"`
ReceiptHash common.Hash `json:"receiptsRoot" gencodec:"required"`
Bloom Bloom `json:"logsBloom" gencodec:"required"`
Difficulty *hexutil.Big `json:"difficulty" gencodec:"required"`
Number *hexutil.Big `json:"number" gencodec:"required"`
GasLimit hexutil.Uint64 `json:"gasLimit" gencodec:"required"`
GasUsed hexutil.Uint64 `json:"gasUsed" gencodec:"required"`
Time hexutil.Uint64 `json:"timestamp" gencodec:"required"`
Extra hexutil.Bytes `json:"extraData" gencodec:"required"`
MixDigest common.Hash `json:"mixHash"`
Nonce BlockNonce `json:"nonce"`
BaseFee *hexutil.Big `json:"baseFeePerGas" rlp:"optional"`
WithdrawalsHash *common.Hash `json:"withdrawalsRoot" rlp:"optional"`
ExcessDataGas *big.Int `json:"excessDataGas" rlp:"optional"`
Hash common.Hash `json:"hash"`
ParentHash common.Hash `json:"parentHash" gencodec:"required"`
UncleHash common.Hash `json:"sha3Uncles" 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"`
Bloom Bloom `json:"logsBloom" gencodec:"required"`
Difficulty *hexutil.Big `json:"difficulty" gencodec:"required"`
Number *hexutil.Big `json:"number" gencodec:"required"`
GasLimit hexutil.Uint64 `json:"gasLimit" gencodec:"required"`
GasUsed hexutil.Uint64 `json:"gasUsed" gencodec:"required"`
Time hexutil.Uint64 `json:"timestamp" gencodec:"required"`
Extra hexutil.Bytes `json:"extraData" gencodec:"required"`
MixDigest common.Hash `json:"mixHash"`
Nonce BlockNonce `json:"nonce"`
BaseFee *hexutil.Big `json:"baseFeePerGas" rlp:"optional"`
WithdrawalsHash *common.Hash `json:"withdrawalsRoot" rlp:"optional"`
ExcessDataGas *hexutil.Uint64 `json:"excessDataGas" rlp:"optional"`
DataGasUsed *hexutil.Uint64 `json:"dataGasUsed" rlp:"optional"`
Hash common.Hash `json:"hash"`
}
var enc Header
enc.ParentHash = h.ParentHash
@@ -54,7 +55,8 @@ func (h Header) MarshalJSON() ([]byte, error) {
enc.Nonce = h.Nonce
enc.BaseFee = (*hexutil.Big)(h.BaseFee)
enc.WithdrawalsHash = h.WithdrawalsHash
enc.ExcessDataGas = h.ExcessDataGas
enc.ExcessDataGas = (*hexutil.Uint64)(h.ExcessDataGas)
enc.DataGasUsed = (*hexutil.Uint64)(h.DataGasUsed)
enc.Hash = h.Hash()
return json.Marshal(&enc)
}
@@ -79,7 +81,8 @@ func (h *Header) UnmarshalJSON(input []byte) error {
Nonce *BlockNonce `json:"nonce"`
BaseFee *hexutil.Big `json:"baseFeePerGas" rlp:"optional"`
WithdrawalsHash *common.Hash `json:"withdrawalsRoot" rlp:"optional"`
ExcessDataGas *big.Int `json:"excessDataGas" rlp:"optional"`
ExcessDataGas *hexutil.Uint64 `json:"excessDataGas" rlp:"optional"`
DataGasUsed *hexutil.Uint64 `json:"dataGasUsed" rlp:"optional"`
}
var dec Header
if err := json.Unmarshal(input, &dec); err != nil {
@@ -149,7 +152,10 @@ func (h *Header) UnmarshalJSON(input []byte) error {
h.WithdrawalsHash = dec.WithdrawalsHash
}
if dec.ExcessDataGas != nil {
h.ExcessDataGas = dec.ExcessDataGas
h.ExcessDataGas = (*uint64)(dec.ExcessDataGas)
}
if dec.DataGasUsed != nil {
h.DataGasUsed = (*uint64)(dec.DataGasUsed)
}
return nil
}
+13 -8
View File
@@ -43,7 +43,8 @@ func (obj *Header) EncodeRLP(_w io.Writer) error {
_tmp1 := obj.BaseFee != nil
_tmp2 := obj.WithdrawalsHash != nil
_tmp3 := obj.ExcessDataGas != nil
if _tmp1 || _tmp2 || _tmp3 {
_tmp4 := obj.DataGasUsed != nil
if _tmp1 || _tmp2 || _tmp3 || _tmp4 {
if obj.BaseFee == nil {
w.Write(rlp.EmptyString)
} else {
@@ -53,21 +54,25 @@ func (obj *Header) EncodeRLP(_w io.Writer) error {
w.WriteBigInt(obj.BaseFee)
}
}
if _tmp2 || _tmp3 {
if _tmp2 || _tmp3 || _tmp4 {
if obj.WithdrawalsHash == nil {
w.Write([]byte{0x80})
} else {
w.WriteBytes(obj.WithdrawalsHash[:])
}
}
if _tmp3 {
if _tmp3 || _tmp4 {
if obj.ExcessDataGas == nil {
w.Write(rlp.EmptyString)
w.Write([]byte{0x80})
} else {
if obj.ExcessDataGas.Sign() == -1 {
return rlp.ErrNegativeBigInt
}
w.WriteBigInt(obj.ExcessDataGas)
w.WriteUint64((*obj.ExcessDataGas))
}
}
if _tmp4 {
if obj.DataGasUsed == nil {
w.Write([]byte{0x80})
} else {
w.WriteUint64((*obj.DataGasUsed))
}
}
w.ListEnd(_tmp0)