Skip to content

Sequencer builder/config parity gaps vs morph-geth #155

Description

@panos-xyz

What happened

A pass over morph-geth miner, genesis morph config, and Engine API vs morph-reth shows several sequencer/builder knobs that geth honors and morph-reth either ignores, hard-codes, or only applies on the packing path.

This is the tracking issue. Child issues cover independently fixable slices.

What I expected

A morph-reth sequencer should produce blocks that a morph-geth validator would accept, and operators should have the same runtime levers they have on geth (miner.gaslimit, genesis tx/payload caps, L1-message overflow behavior).

Audit (geth vs morph-reth)

Must-fix (protocol / sequencer liveness)

Item morph-geth morph-reth today
Block header gasLimit target --miner.gaslimit / miner_setGasLimit; each block ramps toward GasCeil by ~1/1024 Sequencer assemble always copies parent. Header is frozen at genesis (30M). --builder.gaslimit / --miner.gaslimit parse but are unused.
Genesis morph.maxTxPerBlock Mainnet genesis is 100; miner stops packing at that count Field is dropped when reading genesis. Only --morph.max-tx-per-block exists and defaults to unlimited.
Genesis morph.maxTxPayloadBytesPerBlock 122880; ValidateBody rejects oversized L2 payload Parsed, and used as a builder packing cap via CLI default 122880. Not checked on import. A morph-reth validator would accept a block a geth validator would reject.
L1 message that does not fit remaining gas Seal the block with what already fits; leftover L1 messages go to the next block assembleL2Block fails the whole build. Sequencer can stall.

Should-fix (operator knobs / defaults)

Item morph-geth morph-reth today
Block-build time budget --miner.newblock-timeout; unset sanitizes to 3s Packing breaker is hard-coded 1s. Comment says use --builder.deadline, but that flag is not wired into the Morph packing breaker (reth default is 12s for a different job).
Miner gas-price floor when packing --miner.gasprice / miner_setGasPrice, default 0.001 gwei No equivalent packing floor. Txpool minimum_priority_fee is optional and separate.
miner.maxaccountsnum Caps how many accounts the miner pulls from the pool Missing.
miner RPC (setGasLimit, setGasPrice, setExtra) Present (non-public namespace) Missing. setExtra is a no-op on Morph anyway because extra-data must be empty.

Not a gap (checked)

  • miner.extradata: Morph consensus zeros extra-data; both clients require empty extra.
  • Engine API surface (assembleL2Block(V2), newL2Block(V2), validateL2Block, newSafeL2Block, setBlockTags): present.
  • Fee vault, base-fee cap (10 gwei), 1/1024 gasLimit validation of imported headers: present.
  • --morph.max-tx-payload-bytes packing cap default matches genesis 122880.
  • eth_maxPriorityFeePerGas default was already aligned to geth's 0.001 gwei.

Steps to reproduce

  1. Compare a morph-geth sequencer started with defaults against morph-reth on the same chain (mainnet genesis gasLimit 30M, maxTxPerBlock 100, maxTxPayloadBytesPerBlock 122880).
  2. Try to raise block gasLimit at runtime (miner.setGasLimit) — geth ramps, morph-reth cannot.
  3. Assemble a block without --morph.max-tx-per-block 100 — morph-reth may pack more than 100 txs.
  4. Import a block whose L2 payload exceeds 122880 bytes — geth rejects, morph-reth accepts.

Additional context

This is not an OP-stack-style SystemConfig.gasLimit. Morph's consensus node copies gasLimit from assembleL2Block; the EL miner owns the target, same as geth. OP/Base put the value on op-node / L1 SystemConfig; Tempo/Scroll wire --builder.gaslimit on the EL. morph-reth currently does neither on the sequencer assemble path.

Child issues:

  • header gasLimit target (this conversation)
  • genesis maxTxPerBlock ignored
  • payload size not consensus-validated
  • L1 message gas overflow aborts assemble

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions