Skip to content

fix: fall back to sequential store creation when coins are scarce - #1728

Open
TheLastCicada wants to merge 3 commits into
developfrom
fix/org-creation-low-coin-fallback
Open

fix: fall back to sequential store creation when coins are scarce#1728
TheLastCicada wants to merge 3 commits into
developfrom
fix/org-creation-low-coin-fallback

Conversation

@TheLastCicada

@TheLastCicada TheLastCicada commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Org creation required 4 spendable coins upfront and timed out when a freshly funded wallet held a single coin. One coin is now enough to start: the parallel store creations already retry transient wallet errors, so scarce coins serialize them, each waiting for the previous spend's change to confirm. With plenty of coins the four creations still run fully in parallel.
  • The wallet's real coin-selection errors ("Can't select amount higher than our spendable balance", "greater than max spendable balance in a block", "Not enough coins to create new data layer singleton" — see chia's coin_selection.py / data_layer_wallet.py) are now classified as retryable coin shortages. The previous "No spendable coins" pattern matches no current chia error; it is retained defensively.
  • Coin shortages retry on a time budget (15 minutes) instead of a fixed attempt count, since a serialized sequence must survive several block confirmations. Other transient wallet errors keep the attempt budget. The shared createStoreWithRetryBudget helper replaces the duplicated v1/v2 retry loops and is also used by the V2-upgrade registry store creation, so the policy is uniform.
  • The relaxed gate still requires the wallet's combined usable balance to cover every remaining store (new pure evaluateSpendableCoins check): a wallet whose single coin funds one store but not four fails fast instead of spending part of the batch and stranding the org with orphaned stores.

Test plan

  • New spec tests/v2/integration/store-creation-retry.spec.js (14 tests): shortage classification, sequential fallback with four creations sharing one coin, time-budget retries beyond the attempt budget, deadline exhaustion, attempt budget for non-coin transient errors, persist-failure isolation, and the combined-balance sufficiency gate.
  • Full v1 suite: 208 passing. Full v2 suite: 1884 passing.
  • Live API run: freshly faucet-funded wallet (naturally a single coin) successfully creates an org — the sequential fallback and the split-vs-spend race are only exercisable against a real wallet, since simulator mode skips coin management.

Merge order

Merge this before the coin-management single-loop PR: it removes the hard 4-coin gate that the new 5-minute cadence would otherwise need to satisfy in time.


Note

Medium Risk
Touches wallet coin gating and on-chain org creation retry policy; mitigated by combined-balance fail-fast, shared helper, and integration tests, but live wallet timing can still differ from simulator behavior.

Overview
Org creation no longer blocks on four separate spendable coins. The pre-flight gate now requires one usable coin plus a combined balance that covers every remaining store (and optional mirror spends via getStoreCreationMinTotalMojos), so a single freshly funded coin can start creation while under-funded wallets still fail before partial on-chain work.

Wallet layer: waitForSpendableCoins adds optional minTotalMojos and uses a new pure helper evaluateSpendableCoins for per-coin count and total-amount checks. Chia coin-selection failure messages are classified as coin shortages (isCoinShortageError) and retried on a 15-minute time budget; other transient wallet errors keep the 10-attempt budget.

Store creation: Duplicated v1/v2 parallel retry loops are replaced by shared createStoreWithRetryBudget, which serializes parallel creations when coins are scarce (retry until change confirms). V2 upgrade registry creation uses the same helper.

Tests: tests/v2/integration/store-creation-retry.spec.js covers classification, sequential single-coin behavior, budgets, sufficiency gates, and persist-failure isolation.

Reviewed by Cursor Bugbot for commit b4478b8. Bugbot is set up for automated code reviews on this repo. Configure here.

Org creation required 4 spendable coins upfront and timed out when a
freshly funded wallet held a single coin. One coin is enough: the
parallel store creations already retry transient wallet errors, so
scarce coins serialize them, each waiting for the previous spend's
change to confirm.

Classify the wallet's real coin-selection errors as retryable coin
shortages (the previous "No spendable coins" pattern matches no current
chia error) and retry them on a time budget instead of a fixed attempt
count, since a serialized sequence must survive several block
confirmations. The shared retry helper replaces the duplicated v1/v2
retry loops.
The relaxed one-coin gate let a wallet whose single coin covers one
store but not four start creation, spend part of the batch, and strand
the org with orphaned stores. Gate on the combined usable balance
covering every remaining store, extracted as a pure sufficiency check.

Route the V2-upgrade registry store creation through the shared retry
helper so coin shortages get the same time budget there, and widen the
deadline-exhaustion test timings so a loaded runner cannot flake them.
Comment thread src/models/v2/organizations-v2.model.js Outdated
Base automatically changed from v2-rc2 to develop August 10, 2026 22:42
@TheLastCicada
TheLastCicada changed the base branch from develop to v2-rc2 August 10, 2026 22:57
@TheLastCicada
TheLastCicada deployed to windows-code-signing August 10, 2026 23:01 — with GitHub Actions Active

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Want fixes drafted automatically? Bugbot Autofix can create code changes for findings. A team admin can enable Autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit b4478b8. Configure here.

const spendsPerStore = mirrorRequiresSpend ? 2 : 1;

return storesToCreate.length * minUsableCoinSize * spendsPerStore;
};

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Mirror budget mismatches spend model

Medium Severity

getStoreCreationMinTotalMojos doubles the combined-balance gate per remaining store when DATALAYER_FILE_SERVER_URL is set, but mirrorOrgStores / mirrorOrgStoresV2 run once after creation is marked complete for the full org store set and are fire-and-forget. That over-requires funds before create and under-counts mirrors on resume, so the gate no longer matches real spend geometry or the orphaned-store fail-fast goal.

Additional Locations (2)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit b4478b8. Configure here.

Base automatically changed from v2-rc2 to develop August 13, 2026 13:55
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.

1 participant