Skip to content

feat(dashmate): state sync configuration for tenderdash and drive snapshots - #5292

Draft
PastaPastaPasta wants to merge 14 commits into
v5.1-devfrom
feat/dashmate-state-sync-config
Draft

PastaPastaPasta wants to merge 14 commits into
v5.1-devfrom
feat/dashmate-state-sync-config

Conversation

@PastaPastaPasta

Copy link
Copy Markdown
Member

Supersedes #4521, recreated from a dashpay/platform branch so the full CI (Rust, wallet, Kotlin, Swift, e2e) runs; fork PRs skip those jobs. The commits are unchanged (head 01004943ba). Review history is on #4521.

Issue being fixed or feature implemented

Dashmate plumbing for Tenderdash state sync + Drive snapshot serving. Companion to the drive-abci state sync PR #4648 (which superseded #4520; config surface and env names are its contract) and finishes what #2558 started. Targets the Tenderdash 1.8 line that v5.1-dev pins, which supports every [statesync] option used here (enable, use-p2p, rpc-servers, discovery-time, retries, temp-dir, chunk-request-timeout, fetchers; dashpay/tenderdash#1425 is in 1.8). Merge after #4648: snapshot serving defaults on, and its disk bound (serving-pin lifetime and count cap) lives in Drive.

What was done?

  • New config schema:
    • platform.drive.tenderdash.stateSync = { enabled (base default true — safe: tenderdash self-disables when local state exists, so only fresh nodes consume; local preset false), retries (3), chunkRequestTimeout ('15s', min 5s), fetchersCount (4) }
    • platform.drive.abci.stateSync.snapshots = { enabled (base true, local false), frequencySeconds (600, min 60), maxCount (6, min 2) }
  • Tenderdash config template: [statesync] templated; use-p2p = true hardcoded — tenderdash RPC is loopback-bound, not gateway-proxied, and has no TLS/auth, so the RPC state-provider mode (≥2 rpc-servers) is not viable between evonodes; deleted the stale trust-height/trust-hash/trust-period keys (removed in tenderdash 1.7, absent in 1.8); added retries.
  • ABCI routing: ListSnapshots/LoadSnapshotChunk route to drive-abci's gRPC endpoint (26670) so snapshot serving never blocks the consensus socket; grpc-concurrency entries added.
  • docker-compose: passes SNAPSHOTS_ENABLED / SNAPSHOTS_FREQUENCY_SECONDS / MAX_NUM_SNAPSHOTS to drive-abci. Checkpoints stay inside the existing drive_abci_data volume (DB_PATH/checkpoints) — no new volume.
  • Config migration keyed 5.1.0, the release this ships in (configs stamped by 4.2.x/5.0.x builds all pass through it; configs without a Drive section are left alone); doctor accounts for snapshot disk headroom (+10 GB when enabled, without downgrading existing severities); docs for both new sections.

Dropped from the old reference branch: maxConcurrentListSnapshots/maxConcurrentSnapshotChunk (don't exist in tenderdash 1.7/1.8), the feat-statesync-improvements image pin (1.7+ ships everything needed), GROVEDB_LATEST_FILE, and the separate checkpoints volume.

How Has This Been Tested?

Full dashmate unit suite (at the original 4.2-based head): 829 passing, 0 failing, including new schema-bounds specs, the migration test (deep-equal against new defaults), doctor severity tests, and template render-sanity (base and local configs rendered and parsed with a real TOML parser — valid, no undefined, correct statesync/routing values). docker-compose.yml YAML-parsed; eslint clean.

After the rebase onto v5.1-dev and the re-key (2026-10-05): stateSyncOptions 9, analyseSystemResourcesFactory 3, verifySystemRequirementsFactory 13, tenderdashConfigTemplate 3 and tenderdashImageMigration 3 specs pass. The migration was checked against all four default configs stamped at the current package version. migrateConfigFileFactory.spec.js needs a built wasm-dpp (through the DI container), so it was left to CI. eslint is clean on the touched files.

Breaking Changes

None. New config keys are added by migration; tenderdash consuming is enabled by default but self-disables on nodes with existing state.

Checklist:

  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have added or updated relevant unit/integration/functional/e2e tests
  • I have made corresponding changes to the documentation if needed

🤖 Generated with Claude Code

@PastaPastaPasta PastaPastaPasta added this to the v5.1.0 milestone Oct 5, 2026
@coderabbitai

coderabbitai Bot commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@thepastaclaw

thepastaclaw commented Oct 5, 2026 •

Copy link
Copy Markdown
Collaborator

🕓 Review not started yet because this PR is a draft.

  • Request normal review — click when the PR is ready for review.
  • Request priority review — click to move this review to the front of the queue.

Commit d002668. Normal review starts when eligible; priority review starts as soon as a slot is available.

PastaPastaPasta and others added 14 commits October 5, 2026 13:54
Adds platform.drive.tenderdash.stateSync (enabled, retries, chunkRequestTimeout, fetchersCount) and platform.drive.abci.stateSync.snapshots (enabled, frequencySeconds, maxCount). Tenderdash 1.7 minimums are encoded in the schema: chunk request timeout of at least 5s, 1-64 fetchers.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Base config enables consuming (tenderdash stateSync) and serving (drive snapshots every 600s, keeping 6). Serving is always on in Tenderdash and a node with local state ignores the consume flag, so the default is safe for existing nodes. The local preset disables both: a local network genesis starts every node from scratch, so there is no populated peer to sync from.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Templates the statesync section from config: enable, retries, chunk-request-timeout and fetchers. use-p2p is hardcoded to true because the RPC state provider needs two reachable RPC servers while dashmate publishes the Tenderdash RPC on loopback only, unproxied and without TLS. Drops the trust-height/trust-hash/trust-period keys removed in Tenderdash 1.7. Routes ListSnapshots and LoadSnapshotChunk to the drive gRPC app alongside CheckTx and bounds their concurrency; OfferSnapshot and ApplySnapshotChunk stay on the consensus socket.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Maps the state sync snapshot config to the SNAPSHOTS_ENABLED, SNAPSHOTS_FREQUENCY_SECONDS and MAX_NUM_SNAPSHOTS envs drive-abci consumes. Checkpoints are written to the default CHECKPOINTS_PATH under DB_PATH, which is already inside the drive_abci_data volume, so no new volume is needed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Keyed at 4.2.0-dev.6, above the 4.2.0-dev.5 the package is at, so the runner picks it up and dev-build stamped configs cross it. Options are pulled from the default config matching each config's name or group, which gives the local preset its disables and everything else the base defaults.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
When drive snapshots are enabled, the doctor adds a conservative 10GB to the required free disk space and says so in the problem message. Checkpoints hard-link unchanged data, so a small fixed headroom is enough. Configs collected by an older dashmate have no state sync options and skip the headroom.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Adds a State Sync section to the tenderdash config doc (consume side, P2P-only rationale, self-disable semantics) and a State Sync Snapshots section to the drive-abci doc (serve side, checkpoint location and cost).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Replaces for-of loops over test fixtures with forEach to satisfy no-loop-func, and drops an unused catch binding.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…on pattern

Judges disk problem severity against the base minimum so enabling snapshots widens when a problem is raised but never downgrades a HIGH shortage to MEDIUM. Accepts fractional minute and hour chunk request timeouts down to 0.1 (all at least 6s, above the 5s Tenderdash floor).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Tenderdash's SyncAny only returns errNoSnapshots (the block sync fallback trigger) when retries > 0, so retries=0 repeats snapshot discovery indefinitely rather than disabling retries - Tenderdash's own sample config comment is wrong about this. Describe 0 as retry-indefinitely in the schema, rendered template, docs, and test. Also annotate the grpc-concurrency block: Tenderdash drops the concurrency map for the routed transport (NewRoutedClientWithAddr passes address and transport only), so the entries, including the pre-existing check_tx one, are declarative until that propagates.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Fullnode and masternode setup disables Platform but keeps the base snapshot default of true, so doctor added 10GB of disk headroom for checkpoints that Drive never creates. Gate the headroom on platform.enable.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…timeout

The 0.1 m/h floor rejects a sliver of valid durations (0.09m = 5.4s) because 5s is a non-terminating decimal in minutes and no regex can hit the boundary exactly. Document the intent and pin it with boundary tests; s and ms spellings express any duration exactly.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The migration was keyed 4.2.0-dev.6, a v4.2 development prerelease. Every
released config is stamped 4.2.x or 5.0.x and is already above that key, so
the runner would skip it and those configs would fail the schema, which now
requires the state sync options. Key it at the release it ships in, as the
migration convention asks, and test it from the current package version.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…nc migration

Keyed at 5.1.0, the state sync migration now runs for every config a 4.2 or
5.0 build stamped, including the partial ones the image migration test
feeds through the whole chain, and threw on a config without a full Drive
section. Skip those, as the other migrations do.

The image migration test asserted the literal 4.2.0 as the resulting config
format version, which already failed on v5.1-dev (#5241 fixed it on
v5.0-dev by asserting the package version). Assert what
getConfigFormatVersion computes instead, which holds whether or not a
migration is keyed above the package version.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@PastaPastaPasta
PastaPastaPasta force-pushed the feat/dashmate-state-sync-config branch from 0100494 to d002668 Compare October 5, 2026 18:55

This branch has not been deployed

No deployments
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