harden tProxy Sv1 session and channel lifecycle - #823
Conversation
f50aa76 to
90fb36b
Compare
ecfe3ed to
903cebd
Compare
|
Clanker review: Correctness issues1.
|
Document that a new vardiff target takes effect with the next mining.notify rather than immediately. This preserves the difficulty advertised with each job so late shares are not checked against a newer target.
Repeated subscribe or authorize requests must not complete setup more than once or flush cached mining notifications repeatedly. Track each response and transition the downstream only on the first complete handshake.
A failed send to one disconnected miner previously aborted the broadcast and starved healthy downstreams of their new difficulty. Finish the fan-out before returning the disconnect action for the failed peer.
An SV1 miner can pipeline setup traffic while its SV2 channel is opening. Cap that per-downstream queue at eight messages and disconnect on the ninth so an unauthenticated peer cannot grow it without bound.
Keep the existing Bitcoin Core IPC integration test aligned with rustfmt output. This is a formatting-only change with no runtime behavior impact.
Make the default trust boundary explicit: payout verification is disabled unless configured, so tProxy otherwise accepts the upstream payout policy. Operators can then make an informed choice when enabling the check.
Channel and group identifiers share routing state, so accepting a reused or reserved identifier can reinterpret later messages for the wrong owner. Reject collisions transactionally, including the aggregated sentinel ID.
Aggregated miners share one job history, but independent keepalive ticks could repeatedly mutate it and deliver different work to peers. Gate mutation by wall-clock time and distribute one shared keepalive job to all eligible downstreams.
Temporary dependency override for stratum-mining/stratum#2319. Revert to `branch = "main"` and run `cargo update -p stratum-core` across all workspaces after the companion PR merges.
The previous atomic handshake flag could not represent subscribe and authorize progress or preserve response and notification ordering. Use an explicit session state and release cached mining notifications only after both setup responses are queued.
tProxy serves typical SV1 miners that may roll block versions, so an upstream job that forbids version rolling cannot be translated safely. Treat such work as incompatible and trigger fallback instead of advertising unusable jobs.
Once the upstream closes a channel, its associated SV1 miner can no longer submit usable work. Cancel that downstream connection at the same lifecycle boundary so it reconnects instead of mining against dead state.
SetExtranoncePrefix is a legitimate in-place channel update, not evidence that the upstream failed. Apply the new upstream-owned prefix while preserving local allocation state and keep the existing channel alive.
Record which downstreams support mining.set_extranonce so that SetExtranoncePrefix can deliver the subscription notification only to those miners and disconnect unsupported ones cleanly.
Prefix transitions only need FIFO ordering between mining.set_extranonce and the first job that uses it. Replace duplicated transition bookkeeping with one pending count and suppress keepalives until the matching job is delivered.
Internal notification conversion can fail when a malformed mining.notify reaches tProxy. Propagate a structured error instead of panicking so the application follows its normal error policy.
A connected socket is not yet an active mining channel and must not contribute to vardiff calculations. Register the miner only after OpenExtendedMiningChannelSuccess establishes the corresponding SV2 channel.
Late shares must be checked with the target, extranonce, and version advertised for their own job rather than the newest downstream state. Retain one active job plus bounded history and clear prior work only on a true clean-jobs transition.
…rent prefix A late joiner's extranonce1 is minted with the current upstream prefix, but the aggregated channel may still hold an active or future job created under a previous prefix. Replaying such a job would make the new miner produce shares the upstream rejects, so keep the request pending until every inherited job matches the current prefix, and flush pending requests when a new job or prev-hash arrives.
Validate shares against each miner advertised work before forwarding and report stale, duplicate, and low-difficulty failures with their standard SV1 codes. Expected filtering at the harder upstream target remains asynchronous in ChannelManager.
Opening an SV2 channel before decoding the first SV1 request lets malformed or out-of-order traffic allocate upstream resources. Parse once through sv1_api, enforce only session ordering in tProxy, and dispatch the queued typed request after channel success.
Exercise clean-jobs behavior through the downstream FIFO, SV1 response path, and ChannelManager boundary. The coverage ensures a clean transition invalidates only its recipient and that later difficulty changes cannot revive stale work.
Parse the first SV1 request through sv1_api before deciding whether to open an upstream channel. Reply with code 25 when mining.submit arrives before subscription, without allocating a channel or disconnecting the miner. Once subscribed, unauthorized workers receive code 24 through the normal handler and may recover on the same connection.
Adapt tProxy and JDC to the channels_sv2 constructor's full-extranonce validation. Route invalid upstream layouts through each application's existing fallback or shutdown policy, while test fixtures continue to assert that their fixed layouts are valid.
The companion channels_sv2 API now returns ExtendedChannelError from upstream-prefix updates. Store that type in the translator error wrapper and use its Debug representation in diagnostics. Keep the existing fallback and shutdown decisions at the call sites. Validated against the local stratum companion, with no dependency or lockfile changes needed for this adaptation.
Upstream now makes past-job retention configurable. Propagate that same configuration to shared SV1 jobs and per-downstream validation contexts, including the channel default for an unset or zero cap. Exercise caps above and below the default through upstream job delivery and the downstream FIFO in both aggregation modes, so SV1 validation does not silently retain a different history from its corresponding channel.
903cebd to
2b463bc
Compare
This PR is built on top of #741 and:
mining.subscribeandmining.authorizecomplete.mining.extranonce.subscribe, notifying supported miners and disconnecting unsupported ones.companion stratum-mining/stratum#2319
Closes #36
Closes #139
Closes #164
Closes #386
Closes #650