Repository navigation
Forward-port #898 and #899 (WatchAddRejected) to master - #910
Merged
Merged
Conversation
- eventsgrpcmaxsubscriptions was described as the watch-set size per gRPC stream. It caps concurrent Subscribe and Watch streams across all connections, and eventsgrpcmaxconns caps connections, not streams. The config reference and the GrpcLimits doc comments named only Subscribe. - Both SDKs said the server silently drops an over-rate SetCursor. Since #441 it answers in-band with CursorRejected RATE_LIMITED. - Two proto comments still said silent-payment matching and BlockTweaks emit "land in a later change"; both shipped. The Go bindings are regenerated for the comment change. Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com> (cherry picked from commit e019c7d)
* events: report a refused watch add in-band with WatchAddRejected An incremental Add* that the watch-set refused (over quota, over the per-add rate limit, over a per-connection cap, missing stream:watch, or malformed as a whole) was logged on the node and dropped. The client got no signal and could believe it was watching addresses it was not. The WatchSet add paths now return the refusal and the net-new items it covered. Both carriers hand it to the outbound task over a blocking channel, like the SetWatchSet result, and emit a WatchAddRejected event (NodeEvent tag 32) on gRPC and its JSON mirror on WS. The event names the kind, the reason with the numbers behind it, and the refused items; a refused descriptor slide says whether the earlier window is kept. The WS per-connection entry cap moves into the watch-set (WatchSet::with_entry_cap), so a capped add is reported like any other and an add that only re-asserts held items is no longer shed at the cap. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * SDKs surface WatchAddRejected and drop refused items from the mirror Both SDKs decode the new event (Rust Event::WatchAddRejected, Go *WatchAddRejected) with its kind, reason, numbers and items. When it arrives, ResilientWatch drops the refused items from its mirror so a reconnect re-registers only what the node holds; a refused descriptor slide falls back to the window the node kept. The event is still handed to the caller. The parity harness renders the event the same way from both SDKs, and two e2e tests drive it over the real binary: an over-quota gRPC add and a WS add over the per-connection entry cap. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * docs: describe WatchAddRejected; RESOURCE_EXHAUSTED is only at stream open The streaming spec gains §7.3.2 on the new event; the quota section, the operator manual (streaming, authentication, Rust and Go SDK chapters) and both SDKs' QuotaExhausted docs stop promising RESOURCE_EXHAUSTED / 429 for an over-quota add and point at the event. CHANGELOG and the release notes describe the fix. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * satd-events-client: build the rejected descriptor with then_some Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * SDKs re-send a rate-limited watch add instead of dropping it A rate limit is transient, so ResilientWatch keeps the items of a RATE_LIMITED WatchAddRejected in its mirror and re-sends them after the node's retry_after_secs or the backoff delay, whichever is later, absorbing the event. Each item has its own retry budget (the backoff's max_retries); once one is spent the add is handled like any other refusal: dropped from the mirror and handed to the caller. The re-send is built from the mirror at send time, so a removal since the refusal wins. A reconnect re-sends the whole mirror and resets the budgets. Rust drives the retries from next(), racing the stream read against the earliest deadline (EventStream::message is cancel-safe). Go schedules a timer that re-checks it is still on the same stream and sends under mu, as caller edits do. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * e2e: ResilientWatch re-sends a watch add the node throttled Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * SP label re-asserts are free; a refused slide falls back past every refusal Review round 1: - A silent-payment add that only re-asserted held targets (a label update) spent a rate token and could come back RATE_LIMITED naming no items. Re-asserted targets are now free and always applied, like a re-asserted script's floor in add_items_priced; only net-new targets are charged, and a refusal names only them. Their label updates apply even when the net-new targets are refused. - ResilientWatch kept one previous window per descriptor, so two refused slides in flight restored the first refused window. Both SDKs now keep a short history of earlier windows: a refused window leaves it, and a refused latest window falls back to the latest earlier one that was not refused. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * clients/go: regenerate bindings for the WatchAddRejected comment Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * docs: open the 0.6.1 notes with the WatchAddRejected fix The fix ships in 0.6.1 from release/0.6, so its changelog bullet and write-up go into the 0.6.1 cycle rather than the 0.6.0 notes it was first written against. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Forward-port to master: the CHANGELOG bullet and docs/release-notes/0.6.1-pre.md stay on release/0.6 and come to master with the 0.6.1 cut. (cherry picked from commit e10c19e)
This was referenced Oct 6, 2026
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.
Brings two fixes merged into
release/0.6for 0.6.1 back tomaster, one commit each, cherry-picked with-x:e019c7dd): corrects the streaming limit docs and stale SDK and proto comments.e10c19e1): the server reports a refused watch add in-band withWatchAddRejected. Both SDKs surface it, andResilientWatchre-sends a rate-limited add.No
mastercommit since therelease/0.6fork touches the code or docs these change, so both apply unchanged. Apart from the release notes, the patch is identical to the one onrelease/0.6.Release notes
#899's
CHANGELOG.mdbullet anddocs/release-notes/0.6.1-pre.mdstay onrelease/0.6. They describe 0.6.1 and will come tomasterwith the 0.6.1 cut, as #901 brought 0.6.0. Nothing is added to0.7.0-pre.md. (#901 expected #899's notes there; that was before #899 moved to 0.6.1.)The Operator Manual on GitHub Pages builds from
master, so the corrected streaming chapters go live when this merges.Merging
"Rebase and merge" keeps the two commits separate, each with its
cherry picked fromline.Verified
Ran locally on this branch:
cargo clippy --all-targets --all-features -- -D warnings,cargo clippy -p satd-events-client --no-default-features --all-targets -- -D warnings, thesatd-eventstests (182), thesatd-events-clienttests with all features (154) and with none (134), thestreaming::,parity::andsdk::e2e tests (66,--features e2e),clients/go/lint.sh,go test ./...,clients/go/gen.shwith no diff ineventspb, andmdbook build docs/manual. The same set passed onrelease/0.6after both merges, which has no push CI.🤖 Generated with Claude Code