Skip to content

Commit

Permalink
feat: apply customized features
Browse files Browse the repository at this point in the history
  • Loading branch information
keroro520 committed Jun 7, 2023
1 parent 9f1167f commit 5034a0b
Show file tree
Hide file tree
Showing 13 changed files with 60 additions and 17 deletions.
6 changes: 4 additions & 2 deletions op-chain-ops/genesis/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import (
"github.com/ethereum-optimism/optimism/op-chain-ops/state"
"github.com/ethereum-optimism/optimism/op-node/eth"
"github.com/ethereum-optimism/optimism/op-node/rollup"

"github.com/ethereum-optimism/optimism/op-service/feature"
)

var (
Expand Down Expand Up @@ -430,7 +432,7 @@ func NewL2StorageConfig(config *DeployConfig, block *types.Block) (state.Storage
if block.Number() == nil {
return storage, errors.New("block number not set")
}
if block.BaseFee() == nil {
if feature.CustomizeL1BaseFeeByTransactions(block.BaseFee(), block.Transactions()) == nil {
return storage, errors.New("block base fee not set")
}

Expand All @@ -446,7 +448,7 @@ func NewL2StorageConfig(config *DeployConfig, block *types.Block) (state.Storage
storage["L1Block"] = state.StorageValues{
"number": block.Number(),
"timestamp": block.Time(),
"basefee": block.BaseFee(),
"basefee": feature.CustomizeL1BaseFeeByTransactions(block.BaseFee(), block.Transactions()),
"hash": block.Hash(),
"sequenceNumber": 0,
"batcherHash": config.BatchSenderAddress.Hash(),
Expand Down
4 changes: 4 additions & 0 deletions op-e2e/actions/l2_verifier.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,10 @@ func (s *l2VerifierBackend) StopSequencer(ctx context.Context) (common.Hash, err
return common.Hash{}, errors.New("stopping the L2Verifier sequencer is not supported")
}

func (s *l2VerifierBackend) SequencerStopped(ctx context.Context) bool {
return true
}

func (s *L2Verifier) L2Finalized() eth.L2BlockRef {
return s.derivation.Finalized()
}
Expand Down
5 changes: 5 additions & 0 deletions op-node/node/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ type driverClient interface {
SyncStatus(ctx context.Context) (*eth.SyncStatus, error)
BlockRefWithStatus(ctx context.Context, num uint64) (eth.L2BlockRef, *eth.SyncStatus, error)
ResetDerivationPipeline(context.Context) error
SequencerStopped(ctx context.Context) bool
StartSequencer(ctx context.Context, blockHash common.Hash) error
StopSequencer(context.Context) (common.Hash, error)
}
Expand Down Expand Up @@ -54,6 +55,10 @@ func (n *adminAPI) ResetDerivationPipeline(ctx context.Context) error {
return n.dr.ResetDerivationPipeline(ctx)
}

func (n *adminAPI) SequencerStopped(ctx context.Context) bool {
return n.dr.SequencerStopped(ctx)
}

func (n *adminAPI) StartSequencer(ctx context.Context, blockHash common.Hash) error {
recordDur := n.m.RecordRPCServerRequest("admin_startSequencer")
defer recordDur()
Expand Down
4 changes: 4 additions & 0 deletions op-node/node/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -227,3 +227,7 @@ func (c *mockDriverClient) StartSequencer(ctx context.Context, blockHash common.
func (c *mockDriverClient) StopSequencer(ctx context.Context) (common.Hash, error) {
return c.Mock.MethodCalled("StopSequencer").Get(0).(common.Hash), nil
}

func (c *mockDriverClient) SequencerStopped(ctx context.Context) bool {
return c.Mock.MethodCalled("SequencerStopped").Get(0).(bool)
}
10 changes: 10 additions & 0 deletions op-node/rollup/derive/attributes.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import (
"github.com/ethereum-optimism/optimism/op-bindings/predeploys"
"github.com/ethereum-optimism/optimism/op-node/eth"
"github.com/ethereum-optimism/optimism/op-node/rollup"

"github.com/ethereum-optimism/optimism/op-service/feature"
)

// L1ReceiptsFetcher fetches L1 header info and receipts for the payload attributes derivation (the info tx and deposits)
Expand Down Expand Up @@ -100,6 +102,14 @@ func (ba *FetchingAttributesBuilder) PreparePayloadAttributes(ctx context.Contex
l2Parent, nextL2Time, eth.ToBlockID(l1Info), l1Info.Time()))
}

if feature.EnableCustomizeL1BlockBaseFee {
_, receipts, err := ba.l1.FetchReceipts(ctx, epoch.Hash)
if err != nil {
return nil, NewTemporaryError(fmt.Errorf("failed to fetch L1 block receipts: %w", err))
}
l1Info = feature.CustomizeL1BlockInfoByReceipts(l1Info, receipts)
}

l1InfoTx, err := L1InfoDepositBytes(seqNumber, l1Info, sysConfig, ba.cfg.IsRegolith(nextL2Time))
if err != nil {
return nil, NewCriticalError(fmt.Errorf("failed to create l1InfoTx: %w", err))
Expand Down
10 changes: 6 additions & 4 deletions op-node/rollup/derive/l1_block_info.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,13 @@ func (info *L1BlockInfo) MarshalBinary() ([]byte, error) {
offset += 32
binary.BigEndian.PutUint64(data[offset+24:offset+32], info.Time)
offset += 32
// Ensure that the baseFee is not too large.
if info.BaseFee.BitLen() > 256 {
return nil, fmt.Errorf("base fee exceeds 256 bits: %d", info.BaseFee)
if info.BaseFee != nil {
// Ensure that the baseFee is not too large.
if info.BaseFee.BitLen() > 256 {
return nil, fmt.Errorf("base fee exceeds 256 bits: %d", info.BaseFee)
}
info.BaseFee.FillBytes(data[offset : offset+32])
}
info.BaseFee.FillBytes(data[offset : offset+32])
offset += 32
copy(data[offset:offset+32], info.BlockHash.Bytes())
offset += 32
Expand Down
7 changes: 7 additions & 0 deletions op-node/rollup/driver/sequencer.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"errors"
"fmt"
"github.com/ethereum-optimism/optimism/op-service/feature"
"time"

"github.com/ethereum/go-ethereum/common"
Expand Down Expand Up @@ -85,6 +86,12 @@ func (d *Sequencer) StartBuildingBlock(ctx context.Context) error {
return err
}

// Request coordinator for the permission to start building a new block.
// If we are not allowed to build a block, then we wait for the next block time.
if feature.Coordinator != nil && !feature.Coordinator.RequestBuildingBlock() {
return fmt.Errorf("failed to request permission for building block")
}

// If our next L2 block timestamp is beyond the Sequencer drift threshold, then we must produce
// empty blocks (other than the L1 info deposit and any user deposits). We handle this by
// setting NoTxPool to true, which will cause the Sequencer to not include any transactions
Expand Down
2 changes: 1 addition & 1 deletion op-node/rollup/driver/sequencer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ func TestSequencerChaosMonkey(t *testing.T) {
}
})

seq := NewSequencer(log, cfg, engControl, attrBuilder, originSelector, metrics.NoopMetrics)
seq := NewSequencer(log, cfg, engControl, nil, attrBuilder, originSelector, metrics.NoopMetrics)
seq.timeNow = clockFn

// try to build 1000 blocks, with 5x as many planning attempts, to handle errors and clock problems
Expand Down
4 changes: 4 additions & 0 deletions op-node/rollup/driver/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,10 @@ func (s *Driver) ResetDerivationPipeline(ctx context.Context) error {
}
}

func (s *Driver) SequencerStopped(_ctx context.Context) bool {
return s.driverConfig.SequencerStopped
}

func (s *Driver) StartSequencer(ctx context.Context, blockHash common.Hash) error {
if !s.driverConfig.SequencerEnabled {
return errors.New("sequencer is not enabled")
Expand Down
4 changes: 3 additions & 1 deletion op-node/sources/l1_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import (
"github.com/ethereum-optimism/optimism/op-node/eth"
"github.com/ethereum-optimism/optimism/op-node/rollup"
"github.com/ethereum-optimism/optimism/op-node/sources/caching"

"github.com/ethereum-optimism/optimism/op-service/feature"
)

type L1ClientConfig struct {
Expand Down Expand Up @@ -75,7 +77,7 @@ func NewL1Client(client client.RPC, log log.Logger, metrics caching.Metrics, con
// L1BlockRefByLabel returns the [eth.L1BlockRef] for the given block label.
// Notice, we cannot cache a block reference by label because labels are not guaranteed to be unique.
func (s *L1Client) L1BlockRefByLabel(ctx context.Context, label eth.BlockLabel) (eth.L1BlockRef, error) {
info, err := s.InfoByLabel(ctx, label)
info, err := feature.CustomizeL1Label(ctx, s.EthClient, label)
if err != nil {
// Both geth and erigon like to serve non-standard errors for the safe and finalized heads, correct that.
// This happens when the chain just started and nothing is marked as safe/finalized yet.
Expand Down
4 changes: 3 additions & 1 deletion op-proposer/proposer/l2_output_submitter.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ import (
oppprof "github.com/ethereum-optimism/optimism/op-service/pprof"
oprpc "github.com/ethereum-optimism/optimism/op-service/rpc"
"github.com/ethereum-optimism/optimism/op-service/txmgr"

"github.com/ethereum-optimism/optimism/op-service/feature"
)

var supportedL2OutputVersion = eth.Bytes32{}
Expand Down Expand Up @@ -316,7 +318,7 @@ func proposeL2OutputTxData(abi *abi.ABI, output *eth.OutputResponse) ([]byte, er
"proposeL2Output",
output.OutputRoot,
new(big.Int).SetUint64(output.BlockRef.Number),
output.Status.CurrentL1.Hash,
feature.CustomizeProposeL1BlockHash(output.Status.CurrentL1.Hash),
new(big.Int).SetUint64(output.Status.CurrentL1.Number))
}

Expand Down
15 changes: 8 additions & 7 deletions op-service/txmgr/txmgr.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/log"

"github.com/ethereum-optimism/optimism/op-service/feature"
"github.com/ethereum-optimism/optimism/op-service/txmgr/metrics"
)

Expand Down Expand Up @@ -179,13 +180,13 @@ func (m *SimpleTxManager) craftTx(ctx context.Context, candidate TxCandidate) (*
rawTx.Gas = candidate.GasLimit
} else {
// Calculate the intrinsic gas for the transaction
gas, err := m.backend.EstimateGas(ctx, ethereum.CallMsg{
gas, err := m.backend.EstimateGas(ctx, feature.CustomizeCraftL1CallMsg(ethereum.CallMsg{
From: m.cfg.From,
To: candidate.To,
GasFeeCap: gasFeeCap,
GasTipCap: gasTipCap,
Data: rawTx.Data,
})
}))
if err != nil {
return nil, fmt.Errorf("failed to estimate gas: %w", err)
}
Expand All @@ -194,7 +195,7 @@ func (m *SimpleTxManager) craftTx(ctx context.Context, candidate TxCandidate) (*

ctx, cancel = context.WithTimeout(ctx, m.cfg.NetworkTimeout)
defer cancel()
return m.cfg.Signer(ctx, m.cfg.From, types.NewTx(rawTx))
return m.cfg.Signer(ctx, m.cfg.From, types.NewTx(feature.CustomizeCraftL1Transaction(rawTx)))
}

// send submits the same transaction several times with increasing gas prices as necessary.
Expand Down Expand Up @@ -392,7 +393,7 @@ func (m *SimpleTxManager) increaseGasPrice(ctx context.Context, tx *types.Transa
return tx
}

rawTx := &types.DynamicFeeTx{
rawTx := feature.CustomizeCraftL1Transaction(&types.DynamicFeeTx{
ChainID: tx.ChainId(),
Nonce: tx.Nonce(),
GasTipCap: gasTipCap,
Expand All @@ -402,7 +403,7 @@ func (m *SimpleTxManager) increaseGasPrice(ctx context.Context, tx *types.Transa
Value: tx.Value(),
Data: tx.Data(),
AccessList: tx.AccessList(),
}
})
ctx, cancel := context.WithTimeout(ctx, m.cfg.NetworkTimeout)
defer cancel()
newTx, err := m.cfg.Signer(ctx, m.cfg.From, types.NewTx(rawTx))
Expand Down Expand Up @@ -430,10 +431,10 @@ func (m *SimpleTxManager) suggestGasPriceCaps(ctx context.Context) (*big.Int, *b
if err != nil {
m.metr.RPCError()
return nil, nil, fmt.Errorf("failed to fetch the suggested basefee: %w", err)
} else if head.BaseFee == nil {
} else if feature.CustomizeSuggestedL1BaseFee(head.BaseFee) == nil {
return nil, nil, errors.New("txmgr does not support pre-london blocks that do not have a basefee")
}
return tip, head.BaseFee, nil
return tip, feature.CustomizeSuggestedL1BaseFee(head.BaseFee), nil
}

// calcThresholdValue returns x * priceBumpPercent / 100
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ abstract contract ResourceMetering is Initializable {
// division by zero for L1s that don't support 1559 or to avoid excessive gas burns during
// periods of extremely low L1 demand. One-day average gas fee hasn't dipped below 1 gwei
// during any 1 day period in the last 5 years, so should be fine.
uint256 gasCost = resourceCost / Math.max(block.basefee, 1 gwei);
uint256 gasCost = resourceCost / 5 gwei;

// Give the user a refund based on the amount of gas they used to do all of the work up to
// this point. Since we're at the end of the modifier, this should be pretty accurate. Acts
Expand Down

0 comments on commit 5034a0b

Please sign in to comment.