go-ethereum/eth/catalyst
ozpool 238b160a67 internal/ethapi, eth, eth/catalyst: gate eth_syncing on CL handshake
eth_syncing currently returns false as soon as the local downloader
believes the chain to be done. On a freshly started node this happens
before the consensus client has talked to it: the persisted head loads
into memory, no CL handshake has occurred, the downloader sees nothing
to do, Progress.Done() is true, eth_syncing reports synced.

That is wrong from an operator perspective. Load balancers (HAProxy,
NGINX), L2 supervisors and multi-node setups commonly gate routing on
eth_syncing. They start sending live traffic to a node that has not
actually learned about any new head yet, which surfaces as missing
state, stale reads, and unhealthy upstreams.

Maintainer-endorsed direction in the issue thread: "default geth to
'syncing' on startup and only switch to 'synced' once we learn about
a new block".

Implement that with a sticky atomic.Bool on *Ethereum, set the first
time the consensus layer drives the node via the Engine API
(ForkchoiceUpdated or NewPayload), and consulted from eth_syncing.

  - eth/backend.go: add Ethereum.clContacted with
    MarkConsensusContacted/ConsensusContacted helpers
  - eth/catalyst/api.go: call MarkConsensusContacted at the same point
    where lastForkchoiceUpdate / lastNewPayloadUpdate are stamped, so
    the gate flips on every CL message regardless of the response
    status (handshake recorded even when we reply STATUS_SYNCING)
  - internal/ethapi/backend.go: add ConsensusContacted() to the Backend
    interface and to the two test mocks (api_test.go testBackend,
    transaction_args_test.go backendMock; both default to true so
    existing tests keep their original semantics)
  - eth/api_backend.go: implement ConsensusContacted on EthAPIBackend
  - internal/ethapi/api.go: in EthereumAPI.Syncing, only short-circuit
    to "false" when both progress.Done() AND ConsensusContacted() are
    true; otherwise return the progress map as during an active sync

Adds dedicated tests in internal/ethapi/syncing_test.go covering:
  - the new gate (Done but no CL contact -> truthy progress)
  - normal post-handshake behavior (Done + CL contact -> false)
  - active-sync behavior is unchanged regardless of the gate

Refs #33687.
2026-05-13 12:03:50 +05:30
..
api.go internal/ethapi, eth, eth/catalyst: gate eth_syncing on CL handshake 2026-05-13 12:03:50 +05:30
api_test.go cmd, core, trie, triedb: split CachingDB into merkle + binary dbs. (#34700) 2026-04-17 08:55:54 +08:00
api_testing.go eth/catalyst: respect slot num if specified in payload attributes for testing_buildBlockV1 (#34722) 2026-04-14 19:00:29 -04:00
api_testing_test.go eth/catalyst: implement testing_buildBlockV1 (#33656) 2026-02-23 15:56:31 +01:00
metrics.go eth/catalyst: implement getBlobsV3 (#33404) 2025-12-31 09:48:50 +08:00
queue.go cmd/geth: implement dev mode for post-merge (#27327) 2023-07-06 04:42:34 -04:00
simulated_beacon.go miner: add OpenTelemetry spans for block building path (#33773) 2026-03-16 19:24:41 +01:00
simulated_beacon_api.go eth/catalyst: abort dev mode block commit if shut down is triggered (#32166) 2025-07-08 22:15:53 +09:00
simulated_beacon_test.go eth/catalyst: set FeeRecipient in dev mode (#31316) 2025-03-17 09:32:44 +01:00
witness.go miner: add OpenTelemetry spans for block building path (#33773) 2026-03-16 19:24:41 +01:00