feat(zcash_local_net): pin the zainod child's logging env and bound the readiness wait#283
Open
zancas wants to merge 1 commit into
Open
feat(zcash_local_net): pin the zainod child's logging env and bound the readiness wait#283zancas wants to merge 1 commit into
zancas wants to merge 1 commit into
Conversation
…he readiness wait The harness reads zainod's log as an API: launch::wait's readiness scan matches the "Zaino Indexer started successfully." line, and the indexer-convergence barrier parses the "Syncing block, height: N" markers. Both are info-level tracing events, and zainod's filter falls back to info only when RUST_LOG is UNSET — a set-but-empty or restrictive ambient value silences the targets, after which the readiness scan and every convergence wait hang. Zingolib hit exactly this (zingolabs/zingolib#2488): a container task forwarded RUST_LOG set-but-empty and every scenario setup stalled unboundedly. The launcher now owns its child's logging env. LaunchSpec gains an env field carried through both artifact sources (host mode pins it on the Command, container mode emits --env run flags), and the zainod launcher pins RUST_LOG=info unconditionally. Debugging rides the new ZLN_ZAINOD_RUST_LOG knob, whose value is composed with the guard directives zainodlib=info,zaino_state=info appended, so even a restrictive debug filter cannot silence the lines the harness parses. LaunchSpec construction is deduplicated into daemon/one_shot/bare constructors while at it. Silence also fails loudly now instead of hanging or masquerading. launch::wait's indicator scan, previously unbounded, gives up after 300 seconds with the new LaunchError::ReadinessTimeout naming the silenced-logging suspect. The convergence barrier distinguishes a starved observation channel from a lagging indexer: a timeout over a log that never carried a single marker returns the new IndexerSyncError::IndexerSilent, which names the pin and the passthrough knob. The requirements and their resolution are recorded in zingolib-zainod-logging-env-spec.md, committed alongside. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The harness reads zainod's log as an API:
launch::wait's readiness scan matches theZaino Indexer started successfully.line, and the indexer-convergence barrier parses theSyncing block, height: Nmarkers. Both are info-level tracing events, and zainod's filter falls back toinfoonly whenRUST_LOGis unset — a set-but-empty or restrictive ambient value silences those targets, after which the readiness scan and every convergence wait hang. Zingolib hit exactly this failure (zingolabs/zingolib#2488, fixed on its side by zingolabs/zingolib#2487): a container task forwardedRUST_LOGset-but-empty, and every scenario setup stalled unboundedly, costing three days of misattributed forensics.This change makes the launcher own its child's logging environment, closing the class rather than the instance:
LaunchSpecgains anenvfield carried through both artifact sources — host mode pins it on theCommand, container mode emits--envrun flags — and its construction is deduplicated intodaemon/one_shot/bareconstructors.RUST_LOG=infounconditionally. Debugging rides the newZLN_ZAINOD_RUST_LOGknob, whose value is composed with the guard directiveszainodlib=info,zaino_state=infoappended after it, so even a restrictive debug filter cannot silence the lines the harness parses.LaunchError::ReadinessTimeout(generous, because a container-mode launch may pull an image inside the sameruninvocation), and a convergence timeout over a log that never carried a single marker returns the newIndexerSyncError::IndexerSilent— both errors name the silenced-logging diagnosis instead of presenting as anonymous timeouts.The requirements document (
zingolib-zainod-logging-env-spec.md) is committed alongside, with a delivery note recording how each known unknown resolved — in particular that the marker targets arezainodlibandzaino_state, and that the ambient-state acceptance matrix is enforced by construction (the pin overrides inherited env in both modes) and pinned by unit tests on the spawn-command seam.Verification:
cargo check --all-targetsclean,cargo clippy --all-targetsadds no warnings beyond the four pre-existing ondev, andcargo nextest run --package zcash_local_net --libpasses 76/76 including the new composition and command-shape pins. The process-spawning integration suite (zainod_converges_to_validator_tip_after_generate_blocksand siblings) was not run in this environment; it should run in CI or a binary-provisioned checkout before merge.🤖 Generated with Claude Code