mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-02-26 15:47:21 +00:00
core/vm: implement eip-7843: SLOTNUM (#33589)
Implements the slotnum opcode as specified here: https://eips.ethereum.org/EIPS/eip-7843
This commit is contained in:
parent
406a852ec8
commit
f811bfe4fd
28 changed files with 259 additions and 7 deletions
|
|
@ -21,6 +21,7 @@ func (p PayloadAttributes) MarshalJSON() ([]byte, error) {
|
|||
SuggestedFeeRecipient common.Address `json:"suggestedFeeRecipient" gencodec:"required"`
|
||||
Withdrawals []*types.Withdrawal `json:"withdrawals"`
|
||||
BeaconRoot *common.Hash `json:"parentBeaconBlockRoot"`
|
||||
SlotNumber *hexutil.Uint64 `json:"slotNumber"`
|
||||
}
|
||||
var enc PayloadAttributes
|
||||
enc.Timestamp = hexutil.Uint64(p.Timestamp)
|
||||
|
|
@ -28,6 +29,7 @@ func (p PayloadAttributes) MarshalJSON() ([]byte, error) {
|
|||
enc.SuggestedFeeRecipient = p.SuggestedFeeRecipient
|
||||
enc.Withdrawals = p.Withdrawals
|
||||
enc.BeaconRoot = p.BeaconRoot
|
||||
enc.SlotNumber = (*hexutil.Uint64)(p.SlotNumber)
|
||||
return json.Marshal(&enc)
|
||||
}
|
||||
|
||||
|
|
@ -39,6 +41,7 @@ func (p *PayloadAttributes) UnmarshalJSON(input []byte) error {
|
|||
SuggestedFeeRecipient *common.Address `json:"suggestedFeeRecipient" gencodec:"required"`
|
||||
Withdrawals []*types.Withdrawal `json:"withdrawals"`
|
||||
BeaconRoot *common.Hash `json:"parentBeaconBlockRoot"`
|
||||
SlotNumber *hexutil.Uint64 `json:"slotNumber"`
|
||||
}
|
||||
var dec PayloadAttributes
|
||||
if err := json.Unmarshal(input, &dec); err != nil {
|
||||
|
|
@ -62,5 +65,8 @@ func (p *PayloadAttributes) UnmarshalJSON(input []byte) error {
|
|||
if dec.BeaconRoot != nil {
|
||||
p.BeaconRoot = dec.BeaconRoot
|
||||
}
|
||||
if dec.SlotNumber != nil {
|
||||
p.SlotNumber = (*uint64)(dec.SlotNumber)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ func (e ExecutableData) MarshalJSON() ([]byte, error) {
|
|||
Withdrawals []*types.Withdrawal `json:"withdrawals"`
|
||||
BlobGasUsed *hexutil.Uint64 `json:"blobGasUsed"`
|
||||
ExcessBlobGas *hexutil.Uint64 `json:"excessBlobGas"`
|
||||
SlotNumber *hexutil.Uint64 `json:"slotNumber"`
|
||||
}
|
||||
var enc ExecutableData
|
||||
enc.ParentHash = e.ParentHash
|
||||
|
|
@ -58,6 +59,7 @@ func (e ExecutableData) MarshalJSON() ([]byte, error) {
|
|||
enc.Withdrawals = e.Withdrawals
|
||||
enc.BlobGasUsed = (*hexutil.Uint64)(e.BlobGasUsed)
|
||||
enc.ExcessBlobGas = (*hexutil.Uint64)(e.ExcessBlobGas)
|
||||
enc.SlotNumber = (*hexutil.Uint64)(e.SlotNumber)
|
||||
return json.Marshal(&enc)
|
||||
}
|
||||
|
||||
|
|
@ -81,6 +83,7 @@ func (e *ExecutableData) UnmarshalJSON(input []byte) error {
|
|||
Withdrawals []*types.Withdrawal `json:"withdrawals"`
|
||||
BlobGasUsed *hexutil.Uint64 `json:"blobGasUsed"`
|
||||
ExcessBlobGas *hexutil.Uint64 `json:"excessBlobGas"`
|
||||
SlotNumber *hexutil.Uint64 `json:"slotNumber"`
|
||||
}
|
||||
var dec ExecutableData
|
||||
if err := json.Unmarshal(input, &dec); err != nil {
|
||||
|
|
@ -154,5 +157,8 @@ func (e *ExecutableData) UnmarshalJSON(input []byte) error {
|
|||
if dec.ExcessBlobGas != nil {
|
||||
e.ExcessBlobGas = (*uint64)(dec.ExcessBlobGas)
|
||||
}
|
||||
if dec.SlotNumber != nil {
|
||||
e.SlotNumber = (*uint64)(dec.SlotNumber)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,6 +50,13 @@ var (
|
|||
// ExecutionPayloadV3 has the syntax of ExecutionPayloadV2 and appends the new
|
||||
// fields: blobGasUsed and excessBlobGas.
|
||||
PayloadV3 PayloadVersion = 0x3
|
||||
|
||||
// PayloadV4 is the identifier of ExecutionPayloadV4 introduced in amsterdam fork.
|
||||
//
|
||||
// https://github.com/ethereum/execution-apis/blob/main/src/engine/amsterdam.md#executionpayloadv4
|
||||
// ExecutionPayloadV4 has the syntax of ExecutionPayloadV3 and appends the new
|
||||
// field slotNumber.
|
||||
PayloadV4 PayloadVersion = 0x4
|
||||
)
|
||||
|
||||
//go:generate go run github.com/fjl/gencodec -type PayloadAttributes -field-override payloadAttributesMarshaling -out gen_blockparams.go
|
||||
|
|
@ -62,11 +69,13 @@ type PayloadAttributes struct {
|
|||
SuggestedFeeRecipient common.Address `json:"suggestedFeeRecipient" gencodec:"required"`
|
||||
Withdrawals []*types.Withdrawal `json:"withdrawals"`
|
||||
BeaconRoot *common.Hash `json:"parentBeaconBlockRoot"`
|
||||
SlotNumber *uint64 `json:"slotNumber"`
|
||||
}
|
||||
|
||||
// JSON type overrides for PayloadAttributes.
|
||||
type payloadAttributesMarshaling struct {
|
||||
Timestamp hexutil.Uint64
|
||||
Timestamp hexutil.Uint64
|
||||
SlotNumber *hexutil.Uint64
|
||||
}
|
||||
|
||||
//go:generate go run github.com/fjl/gencodec -type ExecutableData -field-override executableDataMarshaling -out gen_ed.go
|
||||
|
|
@ -90,6 +99,7 @@ type ExecutableData struct {
|
|||
Withdrawals []*types.Withdrawal `json:"withdrawals"`
|
||||
BlobGasUsed *uint64 `json:"blobGasUsed"`
|
||||
ExcessBlobGas *uint64 `json:"excessBlobGas"`
|
||||
SlotNumber *uint64 `json:"slotNumber"`
|
||||
}
|
||||
|
||||
// JSON type overrides for executableData.
|
||||
|
|
@ -104,6 +114,7 @@ type executableDataMarshaling struct {
|
|||
Transactions []hexutil.Bytes
|
||||
BlobGasUsed *hexutil.Uint64
|
||||
ExcessBlobGas *hexutil.Uint64
|
||||
SlotNumber *hexutil.Uint64
|
||||
}
|
||||
|
||||
// StatelessPayloadStatusV1 is the result of a stateless payload execution.
|
||||
|
|
@ -313,6 +324,7 @@ func ExecutableDataToBlockNoHash(data ExecutableData, versionedHashes []common.H
|
|||
BlobGasUsed: data.BlobGasUsed,
|
||||
ParentBeaconRoot: beaconRoot,
|
||||
RequestsHash: requestsHash,
|
||||
SlotNumber: data.SlotNumber,
|
||||
}
|
||||
return types.NewBlockWithHeader(header).
|
||||
WithBody(types.Body{Transactions: txs, Uncles: nil, Withdrawals: data.Withdrawals}),
|
||||
|
|
@ -340,6 +352,7 @@ func BlockToExecutableData(block *types.Block, fees *big.Int, sidecars []*types.
|
|||
Withdrawals: block.Withdrawals(),
|
||||
BlobGasUsed: block.BlobGasUsed(),
|
||||
ExcessBlobGas: block.ExcessBlobGas(),
|
||||
SlotNumber: block.SlotNumber(),
|
||||
}
|
||||
|
||||
// Add blobs.
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ type header struct {
|
|||
BlobGasUsed *uint64 `json:"blobGasUsed" rlp:"optional"`
|
||||
ExcessBlobGas *uint64 `json:"excessBlobGas" rlp:"optional"`
|
||||
ParentBeaconBlockRoot *common.Hash `json:"parentBeaconBlockRoot" rlp:"optional"`
|
||||
SlotNumber *uint64 `json:"slotNumber" rlp:"optional"`
|
||||
}
|
||||
|
||||
type headerMarshaling struct {
|
||||
|
|
@ -68,6 +69,7 @@ type headerMarshaling struct {
|
|||
BaseFee *math.HexOrDecimal256
|
||||
BlobGasUsed *math.HexOrDecimal64
|
||||
ExcessBlobGas *math.HexOrDecimal64
|
||||
SlotNumber *math.HexOrDecimal64
|
||||
}
|
||||
|
||||
type bbInput struct {
|
||||
|
|
@ -136,6 +138,7 @@ func (i *bbInput) ToBlock() *types.Block {
|
|||
BlobGasUsed: i.Header.BlobGasUsed,
|
||||
ExcessBlobGas: i.Header.ExcessBlobGas,
|
||||
ParentBeaconRoot: i.Header.ParentBeaconBlockRoot,
|
||||
SlotNumber: i.Header.SlotNumber,
|
||||
}
|
||||
|
||||
// Fill optional values.
|
||||
|
|
|
|||
|
|
@ -102,6 +102,7 @@ type stEnv struct {
|
|||
ParentExcessBlobGas *uint64 `json:"parentExcessBlobGas,omitempty"`
|
||||
ParentBlobGasUsed *uint64 `json:"parentBlobGasUsed,omitempty"`
|
||||
ParentBeaconBlockRoot *common.Hash `json:"parentBeaconBlockRoot"`
|
||||
SlotNumber *uint64 `json:"slotNumber"`
|
||||
}
|
||||
|
||||
type stEnvMarshaling struct {
|
||||
|
|
@ -120,6 +121,7 @@ type stEnvMarshaling struct {
|
|||
ExcessBlobGas *math.HexOrDecimal64
|
||||
ParentExcessBlobGas *math.HexOrDecimal64
|
||||
ParentBlobGasUsed *math.HexOrDecimal64
|
||||
SlotNumber *math.HexOrDecimal64
|
||||
}
|
||||
|
||||
type rejectedTx struct {
|
||||
|
|
@ -195,6 +197,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
|
|||
ExcessBlobGas: pre.Env.ParentExcessBlobGas,
|
||||
BlobGasUsed: pre.Env.ParentBlobGasUsed,
|
||||
BaseFee: pre.Env.ParentBaseFee,
|
||||
SlotNumber: pre.Env.SlotNumber,
|
||||
}
|
||||
header := &types.Header{
|
||||
Time: pre.Env.Timestamp,
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ func (h header) MarshalJSON() ([]byte, error) {
|
|||
BlobGasUsed *math.HexOrDecimal64 `json:"blobGasUsed" rlp:"optional"`
|
||||
ExcessBlobGas *math.HexOrDecimal64 `json:"excessBlobGas" rlp:"optional"`
|
||||
ParentBeaconBlockRoot *common.Hash `json:"parentBeaconBlockRoot" rlp:"optional"`
|
||||
SlotNumber *math.HexOrDecimal64 `json:"slotNumber" rlp:"optional"`
|
||||
}
|
||||
var enc header
|
||||
enc.ParentHash = h.ParentHash
|
||||
|
|
@ -60,6 +61,7 @@ func (h header) MarshalJSON() ([]byte, error) {
|
|||
enc.BlobGasUsed = (*math.HexOrDecimal64)(h.BlobGasUsed)
|
||||
enc.ExcessBlobGas = (*math.HexOrDecimal64)(h.ExcessBlobGas)
|
||||
enc.ParentBeaconBlockRoot = h.ParentBeaconBlockRoot
|
||||
enc.SlotNumber = (*math.HexOrDecimal64)(h.SlotNumber)
|
||||
return json.Marshal(&enc)
|
||||
}
|
||||
|
||||
|
|
@ -86,6 +88,7 @@ func (h *header) UnmarshalJSON(input []byte) error {
|
|||
BlobGasUsed *math.HexOrDecimal64 `json:"blobGasUsed" rlp:"optional"`
|
||||
ExcessBlobGas *math.HexOrDecimal64 `json:"excessBlobGas" rlp:"optional"`
|
||||
ParentBeaconBlockRoot *common.Hash `json:"parentBeaconBlockRoot" rlp:"optional"`
|
||||
SlotNumber *math.HexOrDecimal64 `json:"slotNumber" rlp:"optional"`
|
||||
}
|
||||
var dec header
|
||||
if err := json.Unmarshal(input, &dec); err != nil {
|
||||
|
|
@ -155,5 +158,8 @@ func (h *header) UnmarshalJSON(input []byte) error {
|
|||
if dec.ParentBeaconBlockRoot != nil {
|
||||
h.ParentBeaconBlockRoot = dec.ParentBeaconBlockRoot
|
||||
}
|
||||
if dec.SlotNumber != nil {
|
||||
h.SlotNumber = (*uint64)(dec.SlotNumber)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ func (s stEnv) MarshalJSON() ([]byte, error) {
|
|||
ParentExcessBlobGas *math.HexOrDecimal64 `json:"parentExcessBlobGas,omitempty"`
|
||||
ParentBlobGasUsed *math.HexOrDecimal64 `json:"parentBlobGasUsed,omitempty"`
|
||||
ParentBeaconBlockRoot *common.Hash `json:"parentBeaconBlockRoot"`
|
||||
SlotNumber *math.HexOrDecimal64 `json:"slotNumber"`
|
||||
}
|
||||
var enc stEnv
|
||||
enc.Coinbase = common.UnprefixedAddress(s.Coinbase)
|
||||
|
|
@ -59,6 +60,7 @@ func (s stEnv) MarshalJSON() ([]byte, error) {
|
|||
enc.ParentExcessBlobGas = (*math.HexOrDecimal64)(s.ParentExcessBlobGas)
|
||||
enc.ParentBlobGasUsed = (*math.HexOrDecimal64)(s.ParentBlobGasUsed)
|
||||
enc.ParentBeaconBlockRoot = s.ParentBeaconBlockRoot
|
||||
enc.SlotNumber = (*math.HexOrDecimal64)(s.SlotNumber)
|
||||
return json.Marshal(&enc)
|
||||
}
|
||||
|
||||
|
|
@ -85,6 +87,7 @@ func (s *stEnv) UnmarshalJSON(input []byte) error {
|
|||
ParentExcessBlobGas *math.HexOrDecimal64 `json:"parentExcessBlobGas,omitempty"`
|
||||
ParentBlobGasUsed *math.HexOrDecimal64 `json:"parentBlobGasUsed,omitempty"`
|
||||
ParentBeaconBlockRoot *common.Hash `json:"parentBeaconBlockRoot"`
|
||||
SlotNumber *math.HexOrDecimal64 `json:"slotNumber"`
|
||||
}
|
||||
var dec stEnv
|
||||
if err := json.Unmarshal(input, &dec); err != nil {
|
||||
|
|
@ -154,5 +157,8 @@ func (s *stEnv) UnmarshalJSON(input []byte) error {
|
|||
if dec.ParentBeaconBlockRoot != nil {
|
||||
s.ParentBeaconBlockRoot = dec.ParentBeaconBlockRoot
|
||||
}
|
||||
if dec.SlotNumber != nil {
|
||||
s.SlotNumber = (*uint64)(dec.SlotNumber)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -272,6 +272,14 @@ func (beacon *Beacon) verifyHeader(chain consensus.ChainHeaderReader, header, pa
|
|||
return err
|
||||
}
|
||||
}
|
||||
|
||||
amsterdam := chain.Config().IsAmsterdam(header.Number, header.Time)
|
||||
if amsterdam && header.SlotNumber == nil {
|
||||
return errors.New("header is missing slotNumber")
|
||||
}
|
||||
if !amsterdam && header.SlotNumber != nil {
|
||||
return fmt.Errorf("invalid slotNumber: have %d, expected nil", *header.SlotNumber)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -310,6 +310,8 @@ func (c *Clique) verifyHeader(chain consensus.ChainHeaderReader, header *types.H
|
|||
return fmt.Errorf("invalid blobGasUsed: have %d, expected nil", *header.BlobGasUsed)
|
||||
case header.ParentBeaconRoot != nil:
|
||||
return fmt.Errorf("invalid parentBeaconRoot, have %#x, expected nil", *header.ParentBeaconRoot)
|
||||
case header.SlotNumber != nil:
|
||||
return fmt.Errorf("invalid slotNumber, have %#x, expected nil", *header.SlotNumber)
|
||||
}
|
||||
// All basic checks passed, verify cascading fields
|
||||
return c.verifyCascadingFields(chain, header, parents)
|
||||
|
|
@ -694,6 +696,9 @@ func encodeSigHeader(w io.Writer, header *types.Header) {
|
|||
if header.ParentBeaconRoot != nil {
|
||||
panic("unexpected parent beacon root value in clique")
|
||||
}
|
||||
if header.SlotNumber != nil {
|
||||
panic("unexpected slot number value in clique")
|
||||
}
|
||||
if err := rlp.Encode(w, enc); err != nil {
|
||||
panic("can't encode: " + err.Error())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -283,6 +283,8 @@ func (ethash *Ethash) verifyHeader(chain consensus.ChainHeaderReader, header, pa
|
|||
return fmt.Errorf("invalid blobGasUsed: have %d, expected nil", *header.BlobGasUsed)
|
||||
case header.ParentBeaconRoot != nil:
|
||||
return fmt.Errorf("invalid parentBeaconRoot, have %#x, expected nil", *header.ParentBeaconRoot)
|
||||
case header.SlotNumber != nil:
|
||||
return fmt.Errorf("invalid slotNumber, have %#x, expected nil", *header.SlotNumber)
|
||||
}
|
||||
// Add some fake checks for tests
|
||||
if ethash.fakeDelay != nil {
|
||||
|
|
@ -559,6 +561,9 @@ func (ethash *Ethash) SealHash(header *types.Header) (hash common.Hash) {
|
|||
if header.ParentBeaconRoot != nil {
|
||||
panic("parent beacon root set on ethash")
|
||||
}
|
||||
if header.SlotNumber != nil {
|
||||
panic("slot number set on ethash")
|
||||
}
|
||||
rlp.Encode(hasher, enc)
|
||||
hasher.Sum(hash[:0])
|
||||
return hash
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ func NewEVMBlockContext(header *types.Header, chain ChainContext, author *common
|
|||
baseFee *big.Int
|
||||
blobBaseFee *big.Int
|
||||
random *common.Hash
|
||||
slotNum uint64
|
||||
)
|
||||
|
||||
// If we don't have an explicit author (i.e. not mining), extract from the header
|
||||
|
|
@ -61,6 +62,10 @@ func NewEVMBlockContext(header *types.Header, chain ChainContext, author *common
|
|||
if header.Difficulty.Sign() == 0 {
|
||||
random = &header.MixDigest
|
||||
}
|
||||
if header.SlotNumber != nil {
|
||||
slotNum = *header.SlotNumber
|
||||
}
|
||||
|
||||
return vm.BlockContext{
|
||||
CanTransfer: CanTransfer,
|
||||
Transfer: Transfer,
|
||||
|
|
@ -73,6 +78,7 @@ func NewEVMBlockContext(header *types.Header, chain ChainContext, author *common
|
|||
BlobBaseFee: blobBaseFee,
|
||||
GasLimit: header.GasLimit,
|
||||
Random: random,
|
||||
SlotNum: slotNum,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ func (g Genesis) MarshalJSON() ([]byte, error) {
|
|||
BaseFee *math.HexOrDecimal256 `json:"baseFeePerGas"`
|
||||
ExcessBlobGas *math.HexOrDecimal64 `json:"excessBlobGas"`
|
||||
BlobGasUsed *math.HexOrDecimal64 `json:"blobGasUsed"`
|
||||
SlotNumber *uint64 `json:"slotNumber"`
|
||||
}
|
||||
var enc Genesis
|
||||
enc.Config = g.Config
|
||||
|
|
@ -56,6 +57,7 @@ func (g Genesis) MarshalJSON() ([]byte, error) {
|
|||
enc.BaseFee = (*math.HexOrDecimal256)(g.BaseFee)
|
||||
enc.ExcessBlobGas = (*math.HexOrDecimal64)(g.ExcessBlobGas)
|
||||
enc.BlobGasUsed = (*math.HexOrDecimal64)(g.BlobGasUsed)
|
||||
enc.SlotNumber = g.SlotNumber
|
||||
return json.Marshal(&enc)
|
||||
}
|
||||
|
||||
|
|
@ -77,6 +79,7 @@ func (g *Genesis) UnmarshalJSON(input []byte) error {
|
|||
BaseFee *math.HexOrDecimal256 `json:"baseFeePerGas"`
|
||||
ExcessBlobGas *math.HexOrDecimal64 `json:"excessBlobGas"`
|
||||
BlobGasUsed *math.HexOrDecimal64 `json:"blobGasUsed"`
|
||||
SlotNumber *uint64 `json:"slotNumber"`
|
||||
}
|
||||
var dec Genesis
|
||||
if err := json.Unmarshal(input, &dec); err != nil {
|
||||
|
|
@ -133,5 +136,8 @@ func (g *Genesis) UnmarshalJSON(input []byte) error {
|
|||
if dec.BlobGasUsed != nil {
|
||||
g.BlobGasUsed = (*uint64)(dec.BlobGasUsed)
|
||||
}
|
||||
if dec.SlotNumber != nil {
|
||||
g.SlotNumber = dec.SlotNumber
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -73,6 +73,7 @@ type Genesis struct {
|
|||
BaseFee *big.Int `json:"baseFeePerGas"` // EIP-1559
|
||||
ExcessBlobGas *uint64 `json:"excessBlobGas"` // EIP-4844
|
||||
BlobGasUsed *uint64 `json:"blobGasUsed"` // EIP-4844
|
||||
SlotNumber *uint64 `json:"slotNumber"` // EIP-7843
|
||||
}
|
||||
|
||||
// copy copies the genesis.
|
||||
|
|
@ -122,6 +123,7 @@ func ReadGenesis(db ethdb.Database) (*Genesis, error) {
|
|||
genesis.BaseFee = genesisHeader.BaseFee
|
||||
genesis.ExcessBlobGas = genesisHeader.ExcessBlobGas
|
||||
genesis.BlobGasUsed = genesisHeader.BlobGasUsed
|
||||
genesis.SlotNumber = genesisHeader.SlotNumber
|
||||
|
||||
return &genesis, nil
|
||||
}
|
||||
|
|
@ -547,6 +549,12 @@ func (g *Genesis) toBlockWithRoot(root common.Hash) *types.Block {
|
|||
if conf.IsPrague(num, g.Timestamp) {
|
||||
head.RequestsHash = &types.EmptyRequestsHash
|
||||
}
|
||||
if conf.IsAmsterdam(num, g.Timestamp) {
|
||||
head.SlotNumber = g.SlotNumber
|
||||
if head.SlotNumber == nil {
|
||||
head.SlotNumber = new(uint64)
|
||||
}
|
||||
}
|
||||
}
|
||||
return types.NewBlock(head, &types.Body{Withdrawals: withdrawals}, nil, trie.NewStackTrie(nil))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -422,6 +422,9 @@ func GenerateBadBlock(parent *types.Block, engine consensus.Engine, txs types.Tr
|
|||
beaconRoot := common.HexToHash("0xbeac00")
|
||||
header.ParentBeaconRoot = &beaconRoot
|
||||
}
|
||||
if config.IsAmsterdam(header.Number, header.Time) {
|
||||
header.SlotNumber = new(uint64)
|
||||
}
|
||||
// Assemble and return the final block for sealing
|
||||
body := &types.Body{Transactions: txs}
|
||||
if config.IsShanghai(header.Number, header.Time) {
|
||||
|
|
|
|||
|
|
@ -98,6 +98,9 @@ type Header struct {
|
|||
|
||||
// RequestsHash was added by EIP-7685 and is ignored in legacy headers.
|
||||
RequestsHash *common.Hash `json:"requestsHash" rlp:"optional"`
|
||||
|
||||
// SlotNumber was added by EIP-7843 and is ignored in legacy headers.
|
||||
SlotNumber *uint64 `json:"slotNumber" rlp:"optional"`
|
||||
}
|
||||
|
||||
// field type overrides for gencodec
|
||||
|
|
@ -112,6 +115,7 @@ type headerMarshaling struct {
|
|||
Hash common.Hash `json:"hash"` // adds call to Hash() in MarshalJSON
|
||||
BlobGasUsed *hexutil.Uint64
|
||||
ExcessBlobGas *hexutil.Uint64
|
||||
SlotNumber *hexutil.Uint64
|
||||
}
|
||||
|
||||
// Hash returns the block hash of the header, which is simply the keccak256 hash of its
|
||||
|
|
@ -316,6 +320,10 @@ func CopyHeader(h *Header) *Header {
|
|||
cpy.RequestsHash = new(common.Hash)
|
||||
*cpy.RequestsHash = *h.RequestsHash
|
||||
}
|
||||
if h.SlotNumber != nil {
|
||||
cpy.SlotNumber = new(uint64)
|
||||
*cpy.SlotNumber = *h.SlotNumber
|
||||
}
|
||||
return &cpy
|
||||
}
|
||||
|
||||
|
|
@ -416,6 +424,15 @@ func (b *Block) BlobGasUsed() *uint64 {
|
|||
return blobGasUsed
|
||||
}
|
||||
|
||||
func (b *Block) SlotNumber() *uint64 {
|
||||
var slotNum *uint64
|
||||
if b.header.SlotNumber != nil {
|
||||
slotNum = new(uint64)
|
||||
*slotNum = *b.header.SlotNumber
|
||||
}
|
||||
return slotNum
|
||||
}
|
||||
|
||||
// Size returns the true RLP encoded storage size of the block, either by encoding
|
||||
// and returning it, or returning a previously cached value.
|
||||
func (b *Block) Size() uint64 {
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ func (h Header) MarshalJSON() ([]byte, error) {
|
|||
ExcessBlobGas *hexutil.Uint64 `json:"excessBlobGas" rlp:"optional"`
|
||||
ParentBeaconRoot *common.Hash `json:"parentBeaconBlockRoot" rlp:"optional"`
|
||||
RequestsHash *common.Hash `json:"requestsHash" rlp:"optional"`
|
||||
SlotNumber *hexutil.Uint64 `json:"slotNumber" rlp:"optional"`
|
||||
Hash common.Hash `json:"hash"`
|
||||
}
|
||||
var enc Header
|
||||
|
|
@ -61,6 +62,7 @@ func (h Header) MarshalJSON() ([]byte, error) {
|
|||
enc.ExcessBlobGas = (*hexutil.Uint64)(h.ExcessBlobGas)
|
||||
enc.ParentBeaconRoot = h.ParentBeaconRoot
|
||||
enc.RequestsHash = h.RequestsHash
|
||||
enc.SlotNumber = (*hexutil.Uint64)(h.SlotNumber)
|
||||
enc.Hash = h.Hash()
|
||||
return json.Marshal(&enc)
|
||||
}
|
||||
|
|
@ -89,6 +91,7 @@ func (h *Header) UnmarshalJSON(input []byte) error {
|
|||
ExcessBlobGas *hexutil.Uint64 `json:"excessBlobGas" rlp:"optional"`
|
||||
ParentBeaconRoot *common.Hash `json:"parentBeaconBlockRoot" rlp:"optional"`
|
||||
RequestsHash *common.Hash `json:"requestsHash" rlp:"optional"`
|
||||
SlotNumber *hexutil.Uint64 `json:"slotNumber" rlp:"optional"`
|
||||
}
|
||||
var dec Header
|
||||
if err := json.Unmarshal(input, &dec); err != nil {
|
||||
|
|
@ -169,5 +172,8 @@ func (h *Header) UnmarshalJSON(input []byte) error {
|
|||
if dec.RequestsHash != nil {
|
||||
h.RequestsHash = dec.RequestsHash
|
||||
}
|
||||
if dec.SlotNumber != nil {
|
||||
h.SlotNumber = (*uint64)(dec.SlotNumber)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,7 +43,8 @@ func (obj *Header) EncodeRLP(_w io.Writer) error {
|
|||
_tmp4 := obj.ExcessBlobGas != nil
|
||||
_tmp5 := obj.ParentBeaconRoot != nil
|
||||
_tmp6 := obj.RequestsHash != nil
|
||||
if _tmp1 || _tmp2 || _tmp3 || _tmp4 || _tmp5 || _tmp6 {
|
||||
_tmp7 := obj.SlotNumber != nil
|
||||
if _tmp1 || _tmp2 || _tmp3 || _tmp4 || _tmp5 || _tmp6 || _tmp7 {
|
||||
if obj.BaseFee == nil {
|
||||
w.Write(rlp.EmptyString)
|
||||
} else {
|
||||
|
|
@ -53,41 +54,48 @@ func (obj *Header) EncodeRLP(_w io.Writer) error {
|
|||
w.WriteBigInt(obj.BaseFee)
|
||||
}
|
||||
}
|
||||
if _tmp2 || _tmp3 || _tmp4 || _tmp5 || _tmp6 {
|
||||
if _tmp2 || _tmp3 || _tmp4 || _tmp5 || _tmp6 || _tmp7 {
|
||||
if obj.WithdrawalsHash == nil {
|
||||
w.Write([]byte{0x80})
|
||||
} else {
|
||||
w.WriteBytes(obj.WithdrawalsHash[:])
|
||||
}
|
||||
}
|
||||
if _tmp3 || _tmp4 || _tmp5 || _tmp6 {
|
||||
if _tmp3 || _tmp4 || _tmp5 || _tmp6 || _tmp7 {
|
||||
if obj.BlobGasUsed == nil {
|
||||
w.Write([]byte{0x80})
|
||||
} else {
|
||||
w.WriteUint64((*obj.BlobGasUsed))
|
||||
}
|
||||
}
|
||||
if _tmp4 || _tmp5 || _tmp6 {
|
||||
if _tmp4 || _tmp5 || _tmp6 || _tmp7 {
|
||||
if obj.ExcessBlobGas == nil {
|
||||
w.Write([]byte{0x80})
|
||||
} else {
|
||||
w.WriteUint64((*obj.ExcessBlobGas))
|
||||
}
|
||||
}
|
||||
if _tmp5 || _tmp6 {
|
||||
if _tmp5 || _tmp6 || _tmp7 {
|
||||
if obj.ParentBeaconRoot == nil {
|
||||
w.Write([]byte{0x80})
|
||||
} else {
|
||||
w.WriteBytes(obj.ParentBeaconRoot[:])
|
||||
}
|
||||
}
|
||||
if _tmp6 {
|
||||
if _tmp6 || _tmp7 {
|
||||
if obj.RequestsHash == nil {
|
||||
w.Write([]byte{0x80})
|
||||
} else {
|
||||
w.WriteBytes(obj.RequestsHash[:])
|
||||
}
|
||||
}
|
||||
if _tmp7 {
|
||||
if obj.SlotNumber == nil {
|
||||
w.Write([]byte{0x80})
|
||||
} else {
|
||||
w.WriteUint64((*obj.SlotNumber))
|
||||
}
|
||||
}
|
||||
w.ListEnd(_tmp0)
|
||||
return w.Flush()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ var activators = map[int]func(*JumpTable){
|
|||
7702: enable7702,
|
||||
7939: enable7939,
|
||||
8024: enable8024,
|
||||
7843: enable7843,
|
||||
}
|
||||
|
||||
// EnableEIP enables the given EIP on the config.
|
||||
|
|
@ -579,3 +580,19 @@ func enable7702(jt *JumpTable) {
|
|||
jt[STATICCALL].dynamicGas = gasStaticCallEIP7702
|
||||
jt[DELEGATECALL].dynamicGas = gasDelegateCallEIP7702
|
||||
}
|
||||
|
||||
// opSlotNum enables the SLOTNUM opcode
|
||||
func opSlotNum(pc *uint64, evm *EVM, scope *ScopeContext) ([]byte, error) {
|
||||
scope.Stack.push(uint256.NewInt(evm.Context.SlotNum))
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// enable7843 enables the SLOTNUM opcode as specified in EIP-7843.
|
||||
func enable7843(jt *JumpTable) {
|
||||
jt[SLOTNUM] = &operation{
|
||||
execute: opSlotNum,
|
||||
constantGas: GasQuickStep,
|
||||
minStack: minStack(0, 1),
|
||||
maxStack: maxStack(0, 1),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,6 +66,7 @@ type BlockContext struct {
|
|||
BaseFee *big.Int // Provides information for BASEFEE (0 if vm runs with NoBaseFee flag and 0 gas price)
|
||||
BlobBaseFee *big.Int // Provides information for BLOBBASEFEE (0 if vm runs with NoBaseFee flag and 0 blob gas price)
|
||||
Random *common.Hash // Provides information for PREVRANDAO
|
||||
SlotNum uint64 // Provides information for SLOTNUM
|
||||
}
|
||||
|
||||
// TxContext provides the EVM with information about a transaction.
|
||||
|
|
@ -144,6 +145,8 @@ func NewEVM(blockCtx BlockContext, statedb StateDB, chainConfig *params.ChainCon
|
|||
evm.precompiles = activePrecompiledContracts(evm.chainRules)
|
||||
|
||||
switch {
|
||||
case evm.chainRules.IsAmsterdam:
|
||||
evm.table = &amsterdamInstructionSet
|
||||
case evm.chainRules.IsOsaka:
|
||||
evm.table = &osakaInstructionSet
|
||||
case evm.chainRules.IsVerkle:
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ var (
|
|||
verkleInstructionSet = newVerkleInstructionSet()
|
||||
pragueInstructionSet = newPragueInstructionSet()
|
||||
osakaInstructionSet = newOsakaInstructionSet()
|
||||
amsterdamInstructionSet = newAmsterdamInstructionSet()
|
||||
)
|
||||
|
||||
// JumpTable contains the EVM opcodes supported at a given fork.
|
||||
|
|
@ -92,6 +93,12 @@ func newVerkleInstructionSet() JumpTable {
|
|||
return validate(instructionSet)
|
||||
}
|
||||
|
||||
func newAmsterdamInstructionSet() JumpTable {
|
||||
instructionSet := newOsakaInstructionSet()
|
||||
enable7843(&instructionSet) // EIP-7843 (SLOTNUM opcode)
|
||||
return validate(instructionSet)
|
||||
}
|
||||
|
||||
func newOsakaInstructionSet() JumpTable {
|
||||
instructionSet := newPragueInstructionSet()
|
||||
enable7939(&instructionSet) // EIP-7939 (CLZ opcode)
|
||||
|
|
|
|||
|
|
@ -105,6 +105,7 @@ const (
|
|||
BASEFEE OpCode = 0x48
|
||||
BLOBHASH OpCode = 0x49
|
||||
BLOBBASEFEE OpCode = 0x4a
|
||||
SLOTNUM OpCode = 0x4b
|
||||
)
|
||||
|
||||
// 0x50 range - 'storage' and execution.
|
||||
|
|
@ -320,6 +321,7 @@ var opCodeToString = [256]string{
|
|||
BASEFEE: "BASEFEE",
|
||||
BLOBHASH: "BLOBHASH",
|
||||
BLOBBASEFEE: "BLOBBASEFEE",
|
||||
SLOTNUM: "SLOTNUM",
|
||||
|
||||
// 0x50 range - 'storage' and execution.
|
||||
POP: "POP",
|
||||
|
|
@ -502,6 +504,7 @@ var stringToOp = map[string]OpCode{
|
|||
"BASEFEE": BASEFEE,
|
||||
"BLOBHASH": BLOBHASH,
|
||||
"BLOBBASEFEE": BLOBBASEFEE,
|
||||
"SLOTNUM": SLOTNUM,
|
||||
"DELEGATECALL": DELEGATECALL,
|
||||
"STATICCALL": STATICCALL,
|
||||
"CODESIZE": CODESIZE,
|
||||
|
|
|
|||
|
|
@ -212,6 +212,28 @@ func (api *ConsensusAPI) ForkchoiceUpdatedV3(update engine.ForkchoiceStateV1, pa
|
|||
return api.forkchoiceUpdated(update, params, engine.PayloadV3, false)
|
||||
}
|
||||
|
||||
// ForkchoiceUpdatedV4 is equivalent to V3 with the addition of slot number
|
||||
// in the payload attributes. It supports only PayloadAttributesV4.
|
||||
func (api *ConsensusAPI) ForkchoiceUpdatedV4(update engine.ForkchoiceStateV1, params *engine.PayloadAttributes) (engine.ForkChoiceResponse, error) {
|
||||
if params != nil {
|
||||
switch {
|
||||
case params.Withdrawals == nil:
|
||||
return engine.STATUS_INVALID, attributesErr("missing withdrawals")
|
||||
case params.BeaconRoot == nil:
|
||||
return engine.STATUS_INVALID, attributesErr("missing beacon root")
|
||||
case params.SlotNumber == nil:
|
||||
return engine.STATUS_INVALID, attributesErr("missing slot number")
|
||||
case !api.checkFork(params.Timestamp, forks.Amsterdam):
|
||||
return engine.STATUS_INVALID, unsupportedForkErr("fcuV4 must only be called for amsterdam payloads")
|
||||
}
|
||||
}
|
||||
// TODO(matt): the spec requires that fcu is applied when called on a valid
|
||||
// hash, even if params are wrong. To do this we need to split up
|
||||
// forkchoiceUpdate into a function that only updates the head and then a
|
||||
// function that kicks off block construction.
|
||||
return api.forkchoiceUpdated(update, params, engine.PayloadV4, false)
|
||||
}
|
||||
|
||||
func (api *ConsensusAPI) forkchoiceUpdated(update engine.ForkchoiceStateV1, payloadAttributes *engine.PayloadAttributes, payloadVersion engine.PayloadVersion, payloadWitness bool) (engine.ForkChoiceResponse, error) {
|
||||
api.forkchoiceLock.Lock()
|
||||
defer api.forkchoiceLock.Unlock()
|
||||
|
|
@ -345,6 +367,7 @@ func (api *ConsensusAPI) forkchoiceUpdated(update engine.ForkchoiceStateV1, payl
|
|||
Random: payloadAttributes.Random,
|
||||
Withdrawals: payloadAttributes.Withdrawals,
|
||||
BeaconRoot: payloadAttributes.BeaconRoot,
|
||||
SlotNum: payloadAttributes.SlotNumber,
|
||||
Version: payloadVersion,
|
||||
}
|
||||
id := args.Id()
|
||||
|
|
@ -458,6 +481,18 @@ func (api *ConsensusAPI) GetPayloadV5(payloadID engine.PayloadID) (*engine.Execu
|
|||
})
|
||||
}
|
||||
|
||||
// GetPayloadV6 returns a cached payload by id. This endpoint should only
|
||||
// be used after the Amsterdam fork.
|
||||
func (api *ConsensusAPI) GetPayloadV6(payloadID engine.PayloadID) (*engine.ExecutionPayloadEnvelope, error) {
|
||||
return api.getPayload(
|
||||
payloadID,
|
||||
false,
|
||||
[]engine.PayloadVersion{engine.PayloadV4},
|
||||
[]forks.Fork{
|
||||
forks.Amsterdam,
|
||||
})
|
||||
}
|
||||
|
||||
// getPayload will retrieve the specified payload and verify it conforms to the
|
||||
// endpoint's allowed payload versions and forks.
|
||||
//
|
||||
|
|
@ -700,6 +735,33 @@ func (api *ConsensusAPI) NewPayloadV4(ctx context.Context, params engine.Executa
|
|||
return api.newPayload(ctx, params, versionedHashes, beaconRoot, requests, false)
|
||||
}
|
||||
|
||||
// NewPayloadV5 creates an Eth1 block, inserts it in the chain, and returns the status of the chain.
|
||||
func (api *ConsensusAPI) NewPayloadV5(ctx context.Context, params engine.ExecutableData, versionedHashes []common.Hash, beaconRoot *common.Hash, executionRequests []hexutil.Bytes) (engine.PayloadStatusV1, error) {
|
||||
switch {
|
||||
case params.Withdrawals == nil:
|
||||
return invalidStatus, paramsErr("nil withdrawals post-shanghai")
|
||||
case params.ExcessBlobGas == nil:
|
||||
return invalidStatus, paramsErr("nil excessBlobGas post-cancun")
|
||||
case params.BlobGasUsed == nil:
|
||||
return invalidStatus, paramsErr("nil blobGasUsed post-cancun")
|
||||
case versionedHashes == nil:
|
||||
return invalidStatus, paramsErr("nil versionedHashes post-cancun")
|
||||
case beaconRoot == nil:
|
||||
return invalidStatus, paramsErr("nil beaconRoot post-cancun")
|
||||
case executionRequests == nil:
|
||||
return invalidStatus, paramsErr("nil executionRequests post-prague")
|
||||
case params.SlotNumber == nil:
|
||||
return invalidStatus, paramsErr("nil slotnumber post-amsterdam")
|
||||
case !api.checkFork(params.Timestamp, forks.Amsterdam):
|
||||
return invalidStatus, unsupportedForkErr("newPayloadV5 must only be called for amsterdam payloads")
|
||||
}
|
||||
requests := convertRequests(executionRequests)
|
||||
if err := validateRequests(requests); err != nil {
|
||||
return engine.PayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(err)
|
||||
}
|
||||
return api.newPayload(ctx, params, versionedHashes, beaconRoot, requests, false)
|
||||
}
|
||||
|
||||
func (api *ConsensusAPI) newPayload(ctx context.Context, params engine.ExecutableData, versionedHashes []common.Hash, beaconRoot *common.Hash, requests [][]byte, witness bool) (result engine.PayloadStatusV1, err error) {
|
||||
// The locking here is, strictly, not required. Without these locks, this can happen:
|
||||
//
|
||||
|
|
@ -735,6 +797,10 @@ func (api *ConsensusAPI) newPayload(ctx context.Context, params engine.Executabl
|
|||
if params.ExcessBlobGas != nil {
|
||||
ebg = strconv.Itoa(int(*params.ExcessBlobGas))
|
||||
}
|
||||
slotNum := "nil"
|
||||
if params.SlotNumber != nil {
|
||||
slotNum = strconv.Itoa(int(*params.SlotNumber))
|
||||
}
|
||||
log.Warn("Invalid NewPayload params",
|
||||
"params.Number", params.Number,
|
||||
"params.ParentHash", params.ParentHash,
|
||||
|
|
@ -750,6 +816,7 @@ func (api *ConsensusAPI) newPayload(ctx context.Context, params engine.Executabl
|
|||
"params.BaseFeePerGas", params.BaseFeePerGas,
|
||||
"params.BlobGasUsed", bgu,
|
||||
"params.ExcessBlobGas", ebg,
|
||||
"params.SlotNumber", slotNum,
|
||||
"len(params.Transactions)", len(params.Transactions),
|
||||
"len(params.Withdrawals)", len(params.Withdrawals),
|
||||
"beaconRoot", beaconRoot,
|
||||
|
|
|
|||
|
|
@ -1093,6 +1093,18 @@ func (b *Block) ExcessBlobGas(ctx context.Context) (*hexutil.Uint64, error) {
|
|||
return &ret, nil
|
||||
}
|
||||
|
||||
func (b *Block) SlotNumber(ctx context.Context) (*hexutil.Uint64, error) {
|
||||
header, err := b.resolveHeader(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if header.SlotNumber == nil {
|
||||
return nil, nil
|
||||
}
|
||||
ret := hexutil.Uint64(*header.SlotNumber)
|
||||
return &ret, nil
|
||||
}
|
||||
|
||||
// BlockFilterCriteria encapsulates criteria passed to a `logs` accessor inside
|
||||
// a block.
|
||||
type BlockFilterCriteria struct {
|
||||
|
|
|
|||
|
|
@ -971,6 +971,9 @@ func RPCMarshalHeader(head *types.Header) map[string]interface{} {
|
|||
if head.RequestsHash != nil {
|
||||
result["requestsHash"] = head.RequestsHash
|
||||
}
|
||||
if head.SlotNumber != nil {
|
||||
result["slotNumber"] = head.SlotNumber
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ type BuildPayloadArgs struct {
|
|||
Random common.Hash // The provided randomness value
|
||||
Withdrawals types.Withdrawals // The provided withdrawals
|
||||
BeaconRoot *common.Hash // The provided beaconRoot (Cancun)
|
||||
SlotNum *uint64 // The provided slotNumber
|
||||
Version engine.PayloadVersion // Versioning byte for payload id calculation.
|
||||
}
|
||||
|
||||
|
|
@ -57,6 +58,9 @@ func (args *BuildPayloadArgs) Id() engine.PayloadID {
|
|||
if args.BeaconRoot != nil {
|
||||
hasher.Write(args.BeaconRoot[:])
|
||||
}
|
||||
if args.SlotNum != nil {
|
||||
binary.Write(hasher, binary.BigEndian, args.SlotNum)
|
||||
}
|
||||
var out engine.PayloadID
|
||||
copy(out[:], hasher.Sum(nil)[:8])
|
||||
out[0] = byte(args.Version)
|
||||
|
|
@ -218,6 +222,7 @@ func (miner *Miner) buildPayload(args *BuildPayloadArgs, witness bool) (*Payload
|
|||
random: args.Random,
|
||||
withdrawals: args.Withdrawals,
|
||||
beaconRoot: args.BeaconRoot,
|
||||
slotNum: args.SlotNum,
|
||||
noTxs: true,
|
||||
}
|
||||
empty := miner.generateWork(emptyParams, witness)
|
||||
|
|
@ -248,6 +253,7 @@ func (miner *Miner) buildPayload(args *BuildPayloadArgs, witness bool) (*Payload
|
|||
random: args.Random,
|
||||
withdrawals: args.Withdrawals,
|
||||
beaconRoot: args.BeaconRoot,
|
||||
slotNum: args.SlotNum,
|
||||
noTxs: false,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -111,6 +111,7 @@ type generateParams struct {
|
|||
random common.Hash // The randomness generated by beacon chain, empty before the merge
|
||||
withdrawals types.Withdrawals // List of withdrawals to include in block (shanghai field)
|
||||
beaconRoot *common.Hash // The beacon root (cancun field).
|
||||
slotNum *uint64 // The slot number (amsterdam field).
|
||||
noTxs bool // Flag whether an empty block without any transaction is expected
|
||||
|
||||
forceOverrides bool // Flag whether we should overwrite extraData and transactions
|
||||
|
|
@ -274,6 +275,13 @@ func (miner *Miner) prepareWork(genParams *generateParams, witness bool) (*envir
|
|||
header.ExcessBlobGas = &excessBlobGas
|
||||
header.ParentBeaconRoot = genParams.beaconRoot
|
||||
}
|
||||
// Apply EIP-7843.
|
||||
if miner.chainConfig.IsAmsterdam(header.Number, header.Time) {
|
||||
if genParams.slotNum == nil {
|
||||
return nil, errors.New("no slot number set post-amsterdam")
|
||||
}
|
||||
header.SlotNumber = genParams.slotNum
|
||||
}
|
||||
// Could potentially happen if starting to mine in an odd state.
|
||||
// Note genParams.coinbase can be different with header.Coinbase
|
||||
// since clique algorithm can modify the coinbase field in header.
|
||||
|
|
|
|||
|
|
@ -97,6 +97,7 @@ type btHeader struct {
|
|||
BlobGasUsed *uint64
|
||||
ExcessBlobGas *uint64
|
||||
ParentBeaconBlockRoot *common.Hash
|
||||
SlotNumber *uint64
|
||||
}
|
||||
|
||||
type btHeaderMarshaling struct {
|
||||
|
|
@ -109,6 +110,7 @@ type btHeaderMarshaling struct {
|
|||
BaseFeePerGas *math.HexOrDecimal256
|
||||
BlobGasUsed *math.HexOrDecimal64
|
||||
ExcessBlobGas *math.HexOrDecimal64
|
||||
SlotNumber *math.HexOrDecimal64
|
||||
}
|
||||
|
||||
func (t *BlockTest) Run(snapshotter bool, scheme string, witness bool, tracer *tracing.Hooks, postCheck func(error, *core.BlockChain)) (result error) {
|
||||
|
|
@ -343,6 +345,9 @@ func validateHeader(h *btHeader, h2 *types.Header) error {
|
|||
if !reflect.DeepEqual(h.ParentBeaconBlockRoot, h2.ParentBeaconRoot) {
|
||||
return fmt.Errorf("parentBeaconBlockRoot: want: %v have: %v", h.ParentBeaconBlockRoot, h2.ParentBeaconRoot)
|
||||
}
|
||||
if !reflect.DeepEqual(h.SlotNumber, h2.SlotNumber) {
|
||||
return fmt.Errorf("slotNumber: want: %v have: %v", h.SlotNumber, h2.SlotNumber)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ func (b btHeader) MarshalJSON() ([]byte, error) {
|
|||
BlobGasUsed *math.HexOrDecimal64
|
||||
ExcessBlobGas *math.HexOrDecimal64
|
||||
ParentBeaconBlockRoot *common.Hash
|
||||
SlotNumber *math.HexOrDecimal64
|
||||
}
|
||||
var enc btHeader
|
||||
enc.Bloom = b.Bloom
|
||||
|
|
@ -61,6 +62,7 @@ func (b btHeader) MarshalJSON() ([]byte, error) {
|
|||
enc.BlobGasUsed = (*math.HexOrDecimal64)(b.BlobGasUsed)
|
||||
enc.ExcessBlobGas = (*math.HexOrDecimal64)(b.ExcessBlobGas)
|
||||
enc.ParentBeaconBlockRoot = b.ParentBeaconBlockRoot
|
||||
enc.SlotNumber = (*math.HexOrDecimal64)(b.SlotNumber)
|
||||
return json.Marshal(&enc)
|
||||
}
|
||||
|
||||
|
|
@ -88,6 +90,7 @@ func (b *btHeader) UnmarshalJSON(input []byte) error {
|
|||
BlobGasUsed *math.HexOrDecimal64
|
||||
ExcessBlobGas *math.HexOrDecimal64
|
||||
ParentBeaconBlockRoot *common.Hash
|
||||
SlotNumber *math.HexOrDecimal64
|
||||
}
|
||||
var dec btHeader
|
||||
if err := json.Unmarshal(input, &dec); err != nil {
|
||||
|
|
@ -156,5 +159,8 @@ func (b *btHeader) UnmarshalJSON(input []byte) error {
|
|||
if dec.ParentBeaconBlockRoot != nil {
|
||||
b.ParentBeaconBlockRoot = dec.ParentBeaconBlockRoot
|
||||
}
|
||||
if dec.SlotNumber != nil {
|
||||
b.SlotNumber = (*uint64)(dec.SlotNumber)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue