feat(intent_settlement): batch fill/cancel, paginated list_solvers, Solana e2e (+ compile-baseline fix) - #311
Open
ushpraise wants to merge 2 commits into
Conversation
…vortex-protocol#202, stellar-vortex-protocol#203, stellar-vortex-protocol#204) The crate did not compile on main: lib.rs referenced ~12 undefined constants, 9 undefined DataKey variants and 6 undefined Error variants, the Error enum had duplicate discriminants (22 x3, 23 x2), validate_src_token called a non-existent String::get, compute_reputation_score was a pub contract fn taking a non-ABI &SolverRecord, and fill_intent transferred the fill amount and fee three times each. test.rs had also been mangled by bad merges (unclosed fns, empty fn bodies, a duplicate test name, a stale duplicate import, a SolverRecord literal missing a field). The proptest crate never had its dev-deps written to Cargo.lock. Constants (stellar-vortex-protocol#202) — declared with rationale comments matching the existing style; DEFAULT_* alias the historical hard-coded values so initialize() behaviour is unchanged: DEFAULT_MIN_BOND/FILL_WINDOW/INTENT_EXPIRY/PROTOCOL_FEE_BPS = MIN_BOND / 300 / 1800 / 5 MAX_PROTOCOL_FEE_BPS = 1000 (10% ceiling, matches set_config doc) MIN_FILL_WINDOW_SECS = 60, MIN_INTENT_EXPIRY_SECS = 300 MIN_BOND_FLOOR = 10_000_000 (1 USDC) SLASH_COOLDOWN = 3600 (matches slash_cooldown_expires_after_time_window) CANCEL_COOLDOWN = 60, MAX_BATCH_SIZE = 20, MAX_EXTENSION_DURATION = 300 Error enum (stellar-vortex-protocol#203) — removed the collisions, renumbered sequentially to 36, added AmountTooLarge, InvalidConfig, TimelockNotElapsed, NoPendingAdminTransfer, NoPendingDstTokenChange, CancelCooldownNotExpired, BatchTooLarge, ExtensionAlreadyGranted. Replaced the "reuse nearest" Error::ZeroAmount placeholders in the batch guards and request_extension. DataKey enum (stellar-vortex-protocol#204) — added Config, PendingAdmin, PendingDstTokenAdd, PendingDstTokenRemove, AllowedDstTokenList, MinBondMultiplier, UserIntents, CancelCooldown, ExtensionGranted. Other baseline fixes: - validate_src_token: rewritten over a fixed byte buffer via String::copy_into_slice; same accepted formats (EVM 0x+40hex, Solana base58 32-44). - fill_intent: collapsed the triplicated transfer/fee blocks into one CEI-ordered pass (state committed, then one user transfer + one fee transfer). - compute_reputation_score is now pub(crate) (not a contract entrypoint). - added get_pending_admin view (PendingAdmin had no reader). - test.rs: repaired the mangled functions, fixed get_stats() destructuring (now a 3-tuple), Vec::get Option handling, and pre-stellar-vortex-protocol#127 tests that used "0xabc" placeholder src_tokens; proptest advances past SLASH_COOLDOWN between accept+slash steps. cargo build / clippy --all-targets -D warnings / test: green (145 passed).
…olana e2e Closes stellar-vortex-protocol#198 Closes stellar-vortex-protocol#199 Closes stellar-vortex-protocol#201 ## stellar-vortex-protocol#199 — batch_fill_intent / batch_cancel_intent - `batch_fill_intent(solver, fills: Vec<(BytesN<32>, i128)>)` and `batch_cancel_intent(user, intent_ids: Vec<BytesN<32>>)`, both capped at MAX_BATCH_SIZE and reverting the whole batch on any failure (Soroban whole-transaction atomicity), matching batch_submit_intent / batch_accept_intent. - Mixed outcomes in one batch_fill are fine: some pairs complete an intent (Filled), others only advance it (PartiallyFilled + re-opened); OpenIntents / active_intents bookkeeping stays correct across the mix. - batch_cancel_intent checks and stamps the per-user CANCEL_COOLDOWN once for the whole call (via new cancel_intent_core / check_/stamp_ helpers), so a user can clear all their open intents in one tx instead of one per cooldown window. - Auth fix: require_auth() is one-shot per address per invocation, so the loop bodies now call un-gated `*_inner` functions and each batch authorises the actor exactly once. This also fixes the pre-existing batch_submit_intent / batch_accept_intent, which failed with `Auth, ExistingValue` for any batch of more than one item. - Dedicated `Error::BatchTooLarge`, checked before any auth/state change. ## stellar-vortex-protocol#198 — Paginated, enumerable solver listing - `list_solvers(start: u32, limit: u32) -> Vec<Address>`, limit clamped to MAX_BATCH_SIZE, backed by a new instance-storage `DataKey::SolverList` kept in sync by register_solver (append-if-absent) / deregister_solver (remove) — mirrors the add_to/remove_from_dst_token_list pattern (stellar-vortex-protocol#117), including the "already present" guard so re-registration never duplicates. - Storage-cost trade-off documented on `DataKey::SolverList` in the style of the OpenIntents comment. - `indexer/reference-indexer.js`: comment noting list_solvers as the on-chain alternative to full solver_registered/solver_deregistered replay. ## stellar-vortex-protocol#201 — Solana as a fully-supported source chain - validate_src_token already enforces the Solana rules (base58 alphabet excluding 0/O/I/l, 32-44 chars, no 0x prefix) → InvalidSrcToken. No logic change needed beyond the baseline compile fix; this change is docs + tests + removing the "planned" markers. - docs/132-supported-chains.md: Solana promoted to "Supported"; §3.2 rewritten with the on-chain validation rules, base58 alphabet, the 32-byte-pubkey / bs58 verification source, a CLI example, and a decimals-vary warning; new §4.8 SPL-mint table (USDC 6, wSOL 9, BONK 5). Also noted that avalanche/bsc src_tokens are not yet format-checked. - docs/solver-integration-guide.md: per-source-chain table for interpreting src_token / src_amount, incl. resolving a Solana SPL mint and reading its non-uniform decimals. - README: "planned" removed from the Supported Source Chains table; Solana rows added to the decimal-normalization table; MAX_AMOUNT overflow note corrected to Error::AmountTooLarge. ## CI - `[profile.release]` gains `lto = true` (raw wasm 95 KB -> 68 KB). - wasm-size job now installs binaryen and measures the `wasm-opt -Oz` artifact (~61.4 KB) — the size that actually deploys — against a 63 000 byte budget, under Soroban's 64 KB hard limit. The contract has grown close to the limit; a dedicated size-reduction pass is still owed. ## Tests 14 new tests. list_solvers register/deregister/dedupe/pagination; batch fill mixed full+partial, atomic revert, size guard; batch cancel one-cooldown, atomic revert, size guard; Solana end-to-end with the allowlist enabled (EVM + Solana), out-of-range length rejection, 0x-prefix rejection. Local: cargo fmt --check, clippy --all-targets -D warnings, cargo test (158 passed), PROPTEST_CASES=256 bond_conservation (passed), wasm-opt size 61 456 <= 63 000.
|
@ushpraise Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
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.
Closes #201
Closes #199
Closes #198
Why this PR is larger than three features
intent_settlementdid not compile onmain(cargo build→ 50 errors), so none of #198/#199/#201 could be built, tested, or land green on their own. Restoring a compiling, green baseline is the substance of the open issues #202 (undefined constants), #203 (Error enum), #204 (DataKey enum), so this PR closes those too. Commit 1 is the baseline restoration; commit 2 is the three features + docs.Commit 1 — restore a compiling, green baseline (#202, #203, #204)
mainMAX_BATCH_SIZE,SLASH_COOLDOWN,CANCEL_COOLDOWN,DEFAULT_*,MAX_PROTOCOL_FEE_BPS,MIN_FILL_WINDOW_SECS,MIN_INTENT_EXPIRY_SECS,MIN_BOND_FLOOR,MAX_EXTENSION_DURATION)Errorenum (#203)22used ×3,23used ×2 (won't compile); 6 variants referenced but missingAmountTooLarge,InvalidConfig,TimelockNotElapsed,NoPendingAdminTransfer,NoPendingDstTokenChange,CancelCooldownNotExpired,BatchTooLarge,ExtensionAlreadyGranted; replaced theError::ZeroAmount"reuse nearest" placeholdersDataKeyenum (#204)Config,PendingAdmin,PendingDstTokenAdd,PendingDstTokenRemove,AllowedDstTokenList,MinBondMultiplier,UserIntents,CancelCooldown,ExtensionGrantedvalidate_src_tokenString::get, whichsoroban_sdk::Stringdoes not havecopy_into_sliceinto a fixed buffer; accepted formats unchanged (EVM0x+40hex; Solana base58 32–44)compute_reputation_scorepubcontract fn taking&SolverRecord→error: unsupported typepub(crate)(not an entrypoint)fill_intentget_pending_adminPendingAdminhad no readertest.rs/proptest_bond.rsSolverRecordliteral missing a field; several pre-#127 tests used"0xabc"placeholder src_tokens;get_stats()destructured as a 2-tupleSLASH_COOLDOWNbetween accept+slash stepsChosen constant values (please sanity-check per #202)
DEFAULT_MIN_BOND/DEFAULT_FILL_WINDOW/DEFAULT_INTENT_EXPIRY/DEFAULT_PROTOCOL_FEE_BPS= MIN_BOND/FILL_WINDOW/INTENT_EXPIRY/PROTOCOL_FEE_BPS(50 USDC / 300 s / 1800 s / 5 bps)initialize()behaviour is byte-for-byte unchangedMAX_PROTOCOL_FEE_BPS1_000set_config's doc commentMIN_FILL_WINDOW_SECS60set_configdocMIN_INTENT_EXPIRY_SECS300set_configdocMIN_BOND_FLOOR10_000_000SLASH_COOLDOWN3_600(1 h)slash_cooldown_expires_after_time_windowtest'spass_time(3600)CANCEL_COOLDOWN60MAX_BATCH_SIZE20MAX_EXTENSION_DURATION300FILL_WINDOWThere are upstream branches (
fix/error-discriminant-collision,fix/restore-dst-token-not-allowed-variant) touching the same enums — happy to rebase onto whichever lands first.Commit 2 — the three features
#199 —
batch_fill_intent/batch_cancel_intentbatch_fill_intent(solver, fills: Vec<(BytesN<32>, i128)>),batch_cancel_intent(user, intent_ids: Vec<BytesN<32>>); both capped atMAX_BATCH_SIZE, whole-batch revert on any failure.batch_submit_intent/batch_accept_intent:require_auth()may only be called once per address per invocation, so calling the public single-item entrypoints in a loop failed withAuth, ExistingValueon item 2. All four batch fns now authorise the actor once and call un-gated*_innerbodies.batch_cancel_intentchecks + stampsCANCEL_COOLDOWNonce for the call, so a user clears all their open intents in one tx.OpenIntents/active_intentscorrect.#198 —
list_solvers(start, limit)DataKey::SolverList(instance storage,Vec<Address>) kept in sync byregister_solver/deregister_solverusing theadd_to_/remove_from_dst_token_listpattern (Add a view listing all currently allowed dst_tokens #117), including the "already present" guard — deregister + re-register never duplicates.limitclamped toMAX_BATCH_SIZE; empty page past the end.DataKey::SolverListin the style of theOpenIntentscomment.indexer/reference-indexer.jscomment points atlist_solversas the alternative to full event replay.#201 — Solana, end to end
validate_src_token's Solana branch (base58 alphabet excluding0 O I l, 32–44 chars, no0xprefix) is verified against the Solana SDK (Pubkey= 32-byte ed25519 key,bs58Bitcoin alphabet) and the published SPL mint list — noted indocs/132-supported-chains.md§3.2.132-supported-chains.md§2 Solana → Supported; §3.2 rewritten (rules table, alphabet, decimals-vary warning, CLI example); new §4.8 SPL-mint table (USDC 6, USDT 6, wSOL 9, JitoSOL 9, BONK 5).solver-integration-guide.mdgains a per-source-chainsrc_token/src_amounttable incl. resolving a Solana mint and reading its non-uniform decimals. README: "planned" removed, Solana rows in the decimal table.avalanche/bscsrc_tokens are not yet format-checked on-chain (only the 5 EVM chains + Solana are).Tests & CI
list_solversregister/deregister/dedupe/pagination boundaries;batch_fillmixed full+partial, atomic revert, size guard;batch_cancelone-cooldown, atomic revert, size guard; Solana end-to-end with the allowlist enabled, out-of-range length rejection,0x-prefix rejection.wasm-sizeCI job: the contract is ~93 KB raw before any of this.[profile.release]now setslto = true(→ 68 KB raw) and the job installs binaryen and measures thewasm-opt -Ozartifact — the size that actually deploys — against a 63 000-byte budget (under Soroban's 64 KB hard limit). It measures 61 456 bytes. A real size-reduction pass (dead-code audit / splitting rarely-used entrypoints) is still owed and noted in the workflow + CHANGELOG.Local run (test output)