Skip to content

Commit

Permalink
optimism: dynamic gas limit (ethereum#22)
Browse files Browse the repository at this point in the history
  • Loading branch information
protolambda committed Nov 4, 2022
1 parent 296094d commit c1e9b38
Show file tree
Hide file tree
Showing 8 changed files with 41 additions and 12 deletions.
6 changes: 4 additions & 2 deletions consensus/misc/eip1559.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,10 @@ func VerifyEip1559Header(config *params.ChainConfig, parent, header *types.Heade
if !config.IsLondon(parent.Number) {
parentGasLimit = parent.GasLimit * config.ElasticityMultiplier()
}
if err := VerifyGaslimit(parentGasLimit, header.GasLimit); err != nil {
return err
if config.Optimism == nil { // gasLimit can adjust instantly in optimism
if err := VerifyGaslimit(parentGasLimit, header.GasLimit); err != nil {
return err
}
}
// Verify the header is not malformed
if header.BaseFee == nil {
Expand Down
6 changes: 6 additions & 0 deletions core/beacon/gen_blockparams.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions core/beacon/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,15 @@ type PayloadAttributesV1 struct {
// NoTxPool is a field for rollups: if true, the no transactions are taken out of the tx-pool,
// only transactions from the above Transactions list will be included.
NoTxPool bool `json:"noTxPool,omitempty" gencodec:"optional"`
// GasLimit is a field for rollups: if set, this sets the exact gas limit the block produced with.
GasLimit *uint64 `json:"gasLimit,omitempty" gencodec:"optional"`
}

// JSON type overrides for PayloadAttributesV1.
type payloadAttributesMarshaling struct {
Timestamp hexutil.Uint64
Transactions []hexutil.Bytes
GasLimit *hexutil.Uint64
}

//go:generate go run github.com/fjl/gencodec -type ExecutableDataV1 -field-override executableDataMarshaling -out gen_ed.go
Expand Down
7 changes: 7 additions & 0 deletions eth/catalyst/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,9 @@ func (api *ConsensusAPI) ForkchoiceUpdatedV1(update beacon.ForkchoiceStateV1, pa
// sealed by the beacon client. The payload will be requested later, and we
// will replace it arbitrarily many times in between.
if payloadAttributes != nil {
if api.eth.BlockChain().Config().Optimism != nil && payloadAttributes.GasLimit == nil {
return beacon.STATUS_INVALID, beacon.InvalidPayloadAttributes.With(errors.New("gasLimit parameter is required"))
}
transactions := make(types.Transactions, 0, len(payloadAttributes.Transactions))
for i, otx := range payloadAttributes.Transactions {
var tx types.Transaction
Expand All @@ -300,6 +303,7 @@ func (api *ConsensusAPI) ForkchoiceUpdatedV1(update beacon.ForkchoiceStateV1, pa
Random: payloadAttributes.Random,
NoTxPool: payloadAttributes.NoTxPool,
Transactions: transactions,
GasLimit: payloadAttributes.GasLimit,
}
payload, err := api.eth.Miner().BuildPayload(args)
if err != nil {
Expand Down Expand Up @@ -472,6 +476,9 @@ func computePayloadId(headBlockHash common.Hash, params *beacon.PayloadAttribute
hasher.Write(tx)
}
}
if params.GasLimit != nil {
binary.Write(hasher, binary.BigEndian, *params.GasLimit)
}
var out beacon.PayloadID
copy(out[:], hasher.Sum(nil)[:8])
return out
Expand Down
3 changes: 3 additions & 0 deletions miner/miner.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ import (
type Backend interface {
BlockChain() *core.BlockChain
TxPool() *txpool.TxPool
}

type BackendWithHistoricalState interface {
StateAtBlock(block *types.Block, reexec uint64, base *state.StateDB, readOnly bool, preferDisk bool) (statedb *state.StateDB, release tracers.StateReleaseFunc, err error)
}

Expand Down
5 changes: 3 additions & 2 deletions miner/payload_building.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ type BuildPayloadArgs struct {

NoTxPool bool // Optimism addition: option to disable tx pool contents from being included
Transactions []*types.Transaction // Optimism addition: txs forced into the block via engine API
GasLimit *uint64 // Optimism addition: override gas limit of the block to build
}

// Payload wraps the built payload(block waiting for sealing). According to the
Expand Down Expand Up @@ -137,7 +138,7 @@ func (w *worker) buildPayload(args *BuildPayloadArgs) (*Payload, error) {
// Build the initial version with no transaction included. It should be fast
// enough to run. The empty payload can at least make sure there is something
// to deliver for not missing slot.
empty, _, err := w.getSealingBlock(args.Parent, args.Timestamp, args.FeeRecipient, args.Random, true, args.Transactions)
empty, _, err := w.getSealingBlock(args.Parent, args.Timestamp, args.FeeRecipient, args.Random, true, args.Transactions, args.GasLimit)
if err != nil {
return nil, err
}
Expand All @@ -164,7 +165,7 @@ func (w *worker) buildPayload(args *BuildPayloadArgs) (*Payload, error) {
select {
case <-timer.C:
start := time.Now()
block, fees, err := w.getSealingBlock(args.Parent, args.Timestamp, args.FeeRecipient, args.Random, false, args.Transactions)
block, fees, err := w.getSealingBlock(args.Parent, args.Timestamp, args.FeeRecipient, args.Random, false, args.Transactions, args.GasLimit)
if err == nil {
payload.update(block, fees, time.Since(start))
}
Expand Down
19 changes: 13 additions & 6 deletions miner/worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -788,10 +788,12 @@ func (w *worker) makeEnv(parent *types.Block, header *types.Header, coinbase com
// the miner to speed block sealing up a bit.
state, err := w.chain.StateAt(parent.Root())
if err != nil && w.chainConfig.Optimism != nil { // Allow the miner to reorg its own chain arbitrarily deep
var release tracers.StateReleaseFunc
state, release, err = w.eth.StateAtBlock(parent, ^uint64(0), nil, false, false)
state = state.Copy()
release()
if historicalBackend, ok := w.eth.(BackendWithHistoricalState); ok {
var release tracers.StateReleaseFunc
state, release, err = historicalBackend.StateAtBlock(parent, ^uint64(0), nil, false, false)
state = state.Copy()
release()
}
}
if err != nil {
return nil, err
Expand Down Expand Up @@ -976,7 +978,8 @@ type generateParams struct {
noExtra bool // Flag whether the extra field assignment is allowed
noTxs bool // Flag whether an empty block without any transaction is expected

txs types.Transactions // Deposit transactions to include at the start of the block
txs types.Transactions // Deposit transactions to include at the start of the block
gasLimit *uint64 // Optional gas limit override
}

// prepareWork constructs the sealing task according to the given parameters,
Expand Down Expand Up @@ -1027,6 +1030,9 @@ func (w *worker) prepareWork(genParams *generateParams) (*environment, error) {
header.GasLimit = core.CalcGasLimit(parentGasLimit, w.config.GasCeil)
}
}
if genParams.gasLimit != nil { // override gas limit if specified
header.GasLimit = *genParams.gasLimit
}
// Run the consensus preparation with the default or customized consensus engine.
if err := w.engine.Prepare(w.chain, header); err != nil {
log.Error("Failed to prepare header for sealing", "err", err)
Expand Down Expand Up @@ -1240,7 +1246,7 @@ func (w *worker) commit(env *environment, interval func(), update bool, start ti
// getSealingBlock generates the sealing block based on the given parameters.
// The generation result will be passed back via the given channel no matter
// the generation itself succeeds or not.
func (w *worker) getSealingBlock(parent common.Hash, timestamp uint64, coinbase common.Address, random common.Hash, noTxs bool, transactions types.Transactions) (*types.Block, *big.Int, error) {
func (w *worker) getSealingBlock(parent common.Hash, timestamp uint64, coinbase common.Address, random common.Hash, noTxs bool, transactions types.Transactions, gasLimit *uint64) (*types.Block, *big.Int, error) {
req := &getWorkReq{
params: &generateParams{
timestamp: timestamp,
Expand All @@ -1252,6 +1258,7 @@ func (w *worker) getSealingBlock(parent common.Hash, timestamp uint64, coinbase
noExtra: true,
noTxs: noTxs,
txs: transactions,
gasLimit: gasLimit,
},
result: make(chan *newPayloadResult, 1),
}
Expand Down
4 changes: 2 additions & 2 deletions miner/worker_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -637,7 +637,7 @@ func testGetSealingWork(t *testing.T, chainConfig *params.ChainConfig, engine co

// This API should work even when the automatic sealing is not enabled
for _, c := range cases {
block, _, err := w.getSealingBlock(c.parent, timestamp, c.coinbase, c.random, false, nil)
block, _, err := w.getSealingBlock(c.parent, timestamp, c.coinbase, c.random, false, nil, nil)
if c.expectErr {
if err == nil {
t.Error("Expect error but get nil")
Expand All @@ -653,7 +653,7 @@ func testGetSealingWork(t *testing.T, chainConfig *params.ChainConfig, engine co
// This API should work even when the automatic sealing is enabled
w.start()
for _, c := range cases {
block, _, err := w.getSealingBlock(c.parent, timestamp, c.coinbase, c.random, false, nil)
block, _, err := w.getSealingBlock(c.parent, timestamp, c.coinbase, c.random, false, nil, nil)
if c.expectErr {
if err == nil {
t.Error("Expect error but get nil")
Expand Down

0 comments on commit c1e9b38

Please sign in to comment.