go-ethereum/internal/ethapi
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
..
override eth/catalyst: implement testing_buildBlockV1 (#33656) 2026-02-23 15:56:31 +01:00
testdata internal/ethapi: Add timestamp to eth_getTransactionByHash (#33709) 2026-02-02 12:20:16 +01:00
addrlock.go all: update license information (#16089) 2018-02-14 13:49:11 +01:00
api.go internal/ethapi, eth, eth/catalyst: gate eth_syncing on CL handshake 2026-05-13 12:03:50 +05:30
api_test.go internal/ethapi, eth, eth/catalyst: gate eth_syncing on CL handshake 2026-05-13 12:03:50 +05:30
backend.go internal/ethapi, eth, eth/catalyst: gate eth_syncing on CL handshake 2026-05-13 12:03:50 +05:30
dbapi.go all: remove concept of public/private API definitions (#25053) 2022-06-21 12:05:43 +03:00
errors.go core, internal/ethapi: fix incorrect max-initcode RPC error mapping (#34067) 2026-03-23 22:10:32 +08:00
logtracer.go internal/ethapi: add timestamp to logs in eth_simulate (#32831) 2025-10-06 18:19:25 +02:00
simulate.go internal/ethapi: fix withdrawal regression in eth_simulateV1 (#34939) 2026-05-11 20:33:43 -04:00
simulate_test.go internal/ethapi: fix gas cap for eth_simulateV1 (#33952) 2026-03-05 09:09:07 +08:00
syncing_test.go internal/ethapi, eth, eth/catalyst: gate eth_syncing on CL handshake 2026-05-13 12:03:50 +05:30
transaction_args.go core: use uint256 in core.Message (#34934) 2026-05-11 22:25:57 +08:00
transaction_args_test.go internal/ethapi, eth, eth/catalyst: gate eth_syncing on CL handshake 2026-05-13 12:03:50 +05:30