Skip to content

feat(test-tools): add shape-proxy SV2 share-gating proxy#536

Closed
gimballock wants to merge 4 commits into
stratum-mining:mainfrom
marafoundation:feat/shape-proxy-clean
Closed

feat(test-tools): add shape-proxy SV2 share-gating proxy#536
gimballock wants to merge 4 commits into
stratum-mining:mainfrom
marafoundation:feat/shape-proxy-clean

Conversation

@gimballock

Copy link
Copy Markdown
Contributor

Summary

Adds a new test tool that sits between mining devices and a pool, enabling controlled modification of the share
submission rate without touching mining hardware. Modulating share streams against a live pool is otherwise difficult
— miners produce shares at a rate determined by physics, not configuration.

This tool complements the vardiff simulation framework by providing calibration testing against real pool
infrastructure with real miners.

  • Token-bucket gating with supply-relative rate profiles (Track, Step, Ramp, Stall, Burst, Oscillate)
  • Difficulty-weighted supply measurement via count-based rolling window (N=15), stable across vardiff changes
  • HTTP API for dynamic profile control and live status monitoring
  • Connection resilience — upstream reconnects with exponential backoff; miners stay connected during pool disconnects

Architecture

[Miner(s)] <--SV1--> [Translator] <--SV2--> [Shape-Proxy] <--SV2--> [Pool]
                                                 |
                                              HTTP API

Each arriving share is immediately ACKed to the miner (decoupling it from pool behavior), then the gate decides
whether to forward or drop based on the active profile and measured supply rate.

Using with SV1 miners

Most miners only speak Stratum V1. To use them with shape-proxy, place the existing translator_sv2 (from
roles/translator) between the miner and the proxy:

# translator config (translator.toml)
upstream_address = "127.0.0.1:34262"  # shape-proxy's downstream_listen
upstream_authority_pubkey = "<shape-proxy's public key>"
downstream_address = "0.0.0.0:3333"   # what the miner connects to

# shape-proxy config (shape-proxy.toml)
upstream_address = "pool-host:3335"
downstream_listen = "0.0.0.0:34262"

The translator is a pass-through protocol adapter — it doesn't buffer, gate, or modify shares. It adds no meaningful
latency or behavioral change to the share stream. The only operational impact is an additional process to manage.

Test plan

  • cargo test passes for all unit tests (profile factor_at, gate behavior, target_to_difficulty)
  • Connect an SV1 miner → translator → shape-proxy → pool — verify shares flow at Track{1.0}
  • Set Step profile via API — verify pool sees the rate change at the configured time
  • Set Stall profile — verify shares stop forwarding during the stall window then resume
  • Verify difficulty floor prevents pool SetTarget below threshold
  • Verify upstream reconnection — kill pool, wait, restart — miner stays connected, shares resume

Eric Price and others added 3 commits May 31, 2026 22:55
A middlebox that sits between mining devices and a pool, enabling
controlled modification of the share submission rate for testing
pool difficulty adjustment algorithms.

Core capabilities:
- Transparent SV2/Noise proxy with channel management
- Immediate share ACK to miners (decoupled from pool)
- Token bucket share gate driven by configurable rate profiles
- Upstream reconnection with exponential backoff
- Difficulty floor enforcement via SetTarget interception
- HTTP API for dynamic profile control and status monitoring

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
All profiles are supply-relative multipliers (no absolute-rate mode):
- Track, Step, Ramp, Stall, Burst, and Oscillate profiles
- Count-based (N=15) supply window adapts to any share rate
- Difficulty-weighted supply measurement for stable hashrate tracking
- HTTP API for dynamic profile control and status monitoring

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@gimballock gimballock force-pushed the feat/shape-proxy-clean branch 5 times, most recently from 7c3020c to 86246e7 Compare June 3, 2026 05:31
…get)

Point stratum-core dependency to marafoundation/stratum branch
vardiff/simulation-framework at commit 006363aa which includes:
- AcceleratingPartialRetarget as production UpdateRule
- EwmaEstimator (reverts SpmRatioEstimator which had a production bug)
- AsymmetricCusumBoundary with tighten_multiplier=3.0

Pin idna_adapter to 1.1.0 to avoid icu_collections 2.2 which requires
Rust 1.86 (Docker image has 1.85.1).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@gimballock gimballock force-pushed the feat/shape-proxy-clean branch from 86246e7 to 8a976a7 Compare June 3, 2026 05:33
@GitGab19

GitGab19 commented Jun 5, 2026

Copy link
Copy Markdown
Member

While this might be something useful for your investigation related to vardiff, it's definitely not something which we need to add and maintain on this repo.

@GitGab19 GitGab19 closed this Jun 5, 2026
@gimballock

gimballock commented Jun 5, 2026

Copy link
Copy Markdown
Contributor Author

Yeah, this probably isn't the right place for this to live.
I think we will keep the vardiff stuff on our org in GitHub.

The vardiff experiment repo itself has a similar identity crisis. I think I will make an isolated pr just for the final vardiff change, to separate the test framework from the results.

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.

2 participants