Skip to content

feat(zebrad): run a command on chain tip changes (block notify)#10726

Open
upbqdn wants to merge 3 commits into
mainfrom
block-notify
Open

feat(zebrad): run a command on chain tip changes (block notify)#10726
upbqdn wants to merge 3 commits into
mainfrom
block-notify

Conversation

@upbqdn

@upbqdn upbqdn commented Jun 16, 2026

Copy link
Copy Markdown
Member

Motivation

Closes #10727

Solution

Adds a [notify] config section with a single block_notify_command option. A
background task (modeled on the existing block gossip task) waits for tip changes,
gates on SyncStatus::wait_until_close_to_tip (Zebra's analogue of zcashd
suppressing the callback during initial block download), substitutes every %s
with the new tip's block hash (getbestblockhash hex format), and runs the command
via the system shell (/bin/sh -c on Unix, cmd /C on Windows). The command is
detached and reaped in a separate task, so a hung command never blocks block
validation; non-zero exits are logged like zcashd's runCommand. Disabled (no-op
task) when unset.

Matches zcashd's surface deliberately: no timeout, rate-limiting, or dedup. Note
that ChainTipChange coalesces bursts of commits, so under fast sync intermediate
tip hashes may be skipped — only the current best tip fires (harmless for the
canonical use cases).

Tests

  • Unit tests for %s substitution (single/multiple/none) and an assertion that the
    substituted value is exactly the 64-char lowercase-hex getbestblockhash format
    (pins the command-injection-safety invariant).
  • Config tests: default-disabled, TOML round-trip, deny_unknown_fields.
  • Two #[tokio::test]s drive the real spawn path: one proves the shell ran with the
    substituted hash (tempfile side-effect), one proves a non-zero exit (false)
    neither panics nor blocks the caller.
  • New stored config snapshot zebrad/tests/common/configs/v5.2.0.toml; config_tests
    passes. clippy --all-targets -D warnings and fmt --check clean.

Specifications & References

  • zcashd -blocknotify: BlockNotifyCallback (src/init.cpp), fired from
    NotifyBlockTip after ActivateBestChain (src/main.cpp).

AI Disclosure

  • AI tools were used: Claude Code (Anthropic). Used to write the component,
    tests, and wiring, and a multi-agent workflow to design/adversarially-review the
    implementation. The contributor is the responsible author.

PR Checklist

  • The PR title follows conventional commits format.
  • The PR follows the contribution guidelines.
  • This change was discussed in an issue or with the team beforehand.
  • The solution is tested.
  • The documentation and changelogs are up to date.

@upbqdn upbqdn self-assigned this Jun 16, 2026
@upbqdn upbqdn marked this pull request as ready for review June 23, 2026 15:15
@gustavovalverde gustavovalverde self-assigned this Jun 23, 2026
arya2
arya2 previously approved these changes Jun 23, 2026
@gustavovalverde

Copy link
Copy Markdown
Member

@upbqdn just a conflict to resolve to get this merged

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new zebrad runtime component that mirrors zcashd -blocknotify: when the best chain tip changes (and the node is close to the network tip), Zebra runs a configured shell command with %s substituted by the new tip hash.

Changes:

  • Introduces a new [notify] config section (notify.block_notify_command) and wires it into ZebradConfig.
  • Adds a notify component/task that listens for ChainTipChange, gates on SyncStatus::wait_until_close_to_tip, and spawns/reaps the configured command asynchronously.
  • Updates zebrad startup wiring, enables Tokio’s process feature, adds tests/config snapshot, and documents the feature in CHANGELOG.md.

Note: the PR checklist indicates this change was not discussed with the team beforehand (per the PR template checkbox), even though it closes an issue.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
zebrad/tests/common/configs/v5.2.0.toml Adds a new stored default config snapshot including an empty [notify] section.
zebrad/src/config.rs Adds notify to the top-level ZebradConfig so it can be configured via TOML/env/defaults.
zebrad/src/components/notify.rs New block-notify task implementation and config type.
zebrad/src/components/notify/tests.rs Unit + tokio tests for substitution behavior and spawn path behavior.
zebrad/src/components.rs Exposes the new notify component module.
zebrad/src/commands/start.rs Spawns and supervises the block-notify task during zebrad start.
zebrad/Cargo.toml Enables Tokio process feature required for async process spawning.
CHANGELOG.md Documents the new [notify] block_notify_command option under Unreleased.

Comment thread zebrad/src/components/notify.rs
Comment thread zebrad/src/components/notify.rs Outdated
arya2
arya2 previously approved these changes Jun 25, 2026
upbqdn added 2 commits June 26, 2026 14:47
Add a `[notify]` config section with a `block_notify_command` option, Zebra's
equivalent of zcashd's `-blocknotify`. Whenever the best chain tip changes and
the node is close to the network tip, the command is run via the system shell
with every `%s` replaced by the new tip's block hash. The command is detached
and never blocks block validation.
The spawn integration test uses /bin/sh command syntax, which fails under the
Windows cmd /C branch. Gate it to non-Windows; render_command and the non-zero
exit test still cover Windows.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

stdout/stderr are redirected to `/dev/null`, so there is nothing to collect;
`wait()` only needs the exit status and avoids the extra `Output` buffers.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add a block-notify option (zcashd -blocknotify equivalent)

5 participants