diff --git a/beacon/engine/gen_blockmetadata.go b/beacon/engine/gen_blockmetadata.go index 3b0edb54939a..94df6bb786e8 100644 --- a/beacon/engine/gen_blockmetadata.go +++ b/beacon/engine/gen_blockmetadata.go @@ -5,7 +5,6 @@ package engine import ( "encoding/json" "errors" - "math/big" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" @@ -16,13 +15,13 @@ var _ = (*blockMetadataMarshaling)(nil) // MarshalJSON marshals as JSON. func (b BlockMetadata) MarshalJSON() ([]byte, error) { type BlockMetadata struct { - Beneficiary common.Address `json:"beneficiary" gencodec:"required"` - GasLimit uint64 `json:"gasLimit" gencodec:"required"` - Timestamp hexutil.Uint64 `json:"timestamp" gencodec:"required"` - MixHash common.Hash `json:"mixHash" gencodec:"required"` - TxList hexutil.Bytes `json:"txList" gencodec:"required"` - HighestBlockID *big.Int `json:"highestBlockID" gencodec:"required"` - ExtraData []byte `json:"extraData" gencodec:"required"` + Beneficiary common.Address `json:"beneficiary" gencodec:"required"` + GasLimit uint64 `json:"gasLimit" gencodec:"required"` + Timestamp hexutil.Uint64 `json:"timestamp" gencodec:"required"` + MixHash common.Hash `json:"mixHash" gencodec:"required"` + TxList hexutil.Bytes `json:"txList" gencodec:"required"` + ExtraData []byte `json:"extraData" gencodec:"required"` + BasefeeSharingPctg uint8 `json:"basefeeSharingPctg"` } var enc BlockMetadata enc.Beneficiary = b.Beneficiary @@ -30,21 +29,21 @@ func (b BlockMetadata) MarshalJSON() ([]byte, error) { enc.Timestamp = hexutil.Uint64(b.Timestamp) enc.MixHash = b.MixHash enc.TxList = b.TxList - enc.HighestBlockID = b.HighestBlockID enc.ExtraData = b.ExtraData + enc.BasefeeSharingPctg = b.BasefeeSharingPctg return json.Marshal(&enc) } // UnmarshalJSON unmarshals from JSON. func (b *BlockMetadata) UnmarshalJSON(input []byte) error { type BlockMetadata struct { - Beneficiary *common.Address `json:"beneficiary" gencodec:"required"` - GasLimit *uint64 `json:"gasLimit" gencodec:"required"` - Timestamp *hexutil.Uint64 `json:"timestamp" gencodec:"required"` - MixHash *common.Hash `json:"mixHash" gencodec:"required"` - TxList *hexutil.Bytes `json:"txList" gencodec:"required"` - HighestBlockID *big.Int `json:"highestBlockID" gencodec:"required"` - ExtraData []byte `json:"extraData" gencodec:"required"` + Beneficiary *common.Address `json:"beneficiary" gencodec:"required"` + GasLimit *uint64 `json:"gasLimit" gencodec:"required"` + Timestamp *hexutil.Uint64 `json:"timestamp" gencodec:"required"` + MixHash *common.Hash `json:"mixHash" gencodec:"required"` + TxList *hexutil.Bytes `json:"txList" gencodec:"required"` + ExtraData []byte `json:"extraData" gencodec:"required"` + BasefeeSharingPctg *uint8 `json:"basefeeSharingPctg"` } var dec BlockMetadata if err := json.Unmarshal(input, &dec); err != nil { @@ -70,13 +69,12 @@ func (b *BlockMetadata) UnmarshalJSON(input []byte) error { return errors.New("missing required field 'txList' for BlockMetadata") } b.TxList = *dec.TxList - if dec.HighestBlockID == nil { - return errors.New("missing required field 'highestBlockID' for BlockMetadata") - } - b.HighestBlockID = dec.HighestBlockID if dec.ExtraData == nil { return errors.New("missing required field 'extraData' for BlockMetadata") } b.ExtraData = dec.ExtraData + if dec.BasefeeSharingPctg != nil { + b.BasefeeSharingPctg = *dec.BasefeeSharingPctg + } return nil } diff --git a/beacon/engine/types.go b/beacon/engine/types.go index b246c7751500..2931e066c476 100644 --- a/beacon/engine/types.go +++ b/beacon/engine/types.go @@ -64,16 +64,15 @@ type payloadAttributesMarshaling struct { // CHANGE(taiko): BlockMetadata represents a `BlockMetadata` struct defined in // protocol. type BlockMetadata struct { - // Fields defined in `LibData.blockMetadata`. Beneficiary common.Address `json:"beneficiary" gencodec:"required"` GasLimit uint64 `json:"gasLimit" gencodec:"required"` Timestamp uint64 `json:"timestamp" gencodec:"required"` MixHash common.Hash `json:"mixHash" gencodec:"required"` // Extra fields required in taiko-geth. - TxList []byte `json:"txList" gencodec:"required"` - HighestBlockID *big.Int `json:"highestBlockID" gencodec:"required"` - ExtraData []byte `json:"extraData" gencodec:"required"` + TxList []byte `json:"txList" gencodec:"required"` + ExtraData []byte `json:"extraData" gencodec:"required"` + BasefeeSharingPctg uint8 `json:"basefeeSharingPctg"` } // CHANGE(taiko): JSON type overrides for BlockMetadata. diff --git a/core/state/statedb.go b/core/state/statedb.go index ebd2143882ac..0e2743944116 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -138,6 +138,10 @@ type StateDB struct { // Testing hooks onCommit func(states *triestate.Set) // Hook invoked when commit is performed + + // CHANGE(taiko): basefeeSharingPctg of the basefee will be sent to the block.coinbase, + // the remaining will be sent to the treasury address. + BasefeeSharingPctg uint8 } // New creates a new state from a given trie. diff --git a/core/state_processor.go b/core/state_processor.go index f953b1098680..40a9f53819cc 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -169,6 +169,8 @@ func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *commo if err != nil { return nil, err } + // CHANGE(taiko): set `BasefeeSharingPctg` for the current message. + msg.BasefeeSharingPctg = statedb.BasefeeSharingPctg // Create a new context to be used in the EVM environment blockContext := NewEVMBlockContext(header, bc, author) txContext := NewEVMTxContext(msg) diff --git a/core/state_transition.go b/core/state_transition.go index 031979784f9b..bce9bfbfa637 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -149,6 +149,9 @@ type Message struct { // CHANGE(taiko): whether the current transaction is the first TaikoL2.anchor transaction in a block. IsAnchor bool + // CHANGE(taiko): basefeeSharingPctg of the basefee will be sent to the block.coinbase, + // the remaining will be sent to the treasury address. + BasefeeSharingPctg uint8 } // TransactionToMessage converts a transaction into a Message. @@ -467,12 +470,16 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) { fee := new(uint256.Int).SetUint64(st.gasUsed()) fee.Mul(fee, effectiveTipU256) st.state.AddBalance(st.evm.Context.Coinbase, fee) - // CHANGE(taiko): basefee is not burnt, but sent to a treasury instead. + // CHANGE(taiko): basefee is not burnt, but sent to a treasury and block.coinbase instead. if st.evm.ChainConfig().Taiko && st.evm.Context.BaseFee != nil && !st.msg.IsAnchor { - st.state.AddBalance( - st.getTreasuryAddress(), - uint256.MustFromBig(new(big.Int).Mul(st.evm.Context.BaseFee, new(big.Int).SetUint64(st.gasUsed()))), + totalFee := new(big.Int).Mul(st.evm.Context.BaseFee, new(big.Int).SetUint64(st.gasUsed())) + feeCoinbase := new(big.Int).Div( + new(big.Int).Mul(totalFee, new(big.Int).SetUint64(uint64(st.msg.BasefeeSharingPctg))), + new(big.Int).SetUint64(100), ) + feeTreasury := new(big.Int).Sub(totalFee, feeCoinbase) + st.state.AddBalance(st.getTreasuryAddress(), uint256.MustFromBig(feeTreasury)) + st.state.AddBalance(st.evm.Context.Coinbase, uint256.MustFromBig(feeCoinbase)) } } diff --git a/eth/catalyst/api.go b/eth/catalyst/api.go index c37cee4e02eb..0f44a8489ca8 100644 --- a/eth/catalyst/api.go +++ b/eth/catalyst/api.go @@ -382,6 +382,11 @@ func (api *ConsensusAPI) forkchoiceUpdated(update engine.ForkchoiceStateV1, payl if payloadAttributes != nil { // CHANGE(taiko): create a L2 block by Taiko protocol. if isTaiko { + if payloadAttributes.BlockMetadata.BasefeeSharingPctg > 100 { + return valid(nil), engine.InvalidPayloadAttributes.With( + fmt.Errorf("invalid basefeeSharingPctg %d", payloadAttributes.BlockMetadata.BasefeeSharingPctg), + ) + } // No need to check payloadAttribute here, because all its fields are // marked as required. block, err := api.eth.Miner().SealBlockWith( diff --git a/miner/taiko_worker.go b/miner/taiko_worker.go index 3f02d21d174a..b050d7b77eb8 100644 --- a/miner/taiko_worker.go +++ b/miner/taiko_worker.go @@ -170,6 +170,7 @@ func (w *worker) sealBlockWith( defer env.discard() env.header.GasLimit = blkMeta.GasLimit + env.state.BasefeeSharingPctg = blkMeta.BasefeeSharingPctg // Commit transactions. gasLimit := env.header.GasLimit