Repository navigation
feat(interfaces): consolidate and standardize contract error types wi… - #268
Cjay-Cyber-2 merged 5 commits into
Conversation
…th deterministic codes - Add errors.rs module to interfaces crate re-exporting canonical Error enum from astroid-shared - Export Error type cleanly for consumption by all workspace contracts and client SDKs - Add comprehensive unit tests verifying: - Stable u32 discriminants for all error variants (ABI stability) - Required trait implementations (Copy, Clone, Debug, Eq, PartialEq) - Contract error return type usage - Discriminant-to-variant mapping for off-chain SDKs - Uniqueness of all discriminants - Update upgrade.rs to use local Error import from interfaces crate
Link an issueI check every PR against the issue it solves before merging, and I couldn't find one linked here. Add |
Link an issueI check every PR against the issue it solves before merging, and I couldn't find one linked here. Add |
1 similar comment
Link an issueI check every PR against the issue it solves before merging, and I couldn't find one linked here. Add |
…zation test coverage - Export canonical Error at the crate root so SDKs and contracts can use astroid_interfaces::Error directly - Expand error test suite 5 -> 10: ScVal wire round-trip (ScVal::Error(ScError::Contract(code))), generated spec-XDR validation, and sdk::Error/InvokeError conversion round-trips across all 50 variants, driven by a single ALL_VARIANTS table - Fix pre-existing clippy --all-targets lints in budget/multisig tests 🤖 Generated with Codebuff Co-Authored-By: Codebuff <noreply@codebuff.com>
CI checks neededNo checks are visible on this commit. Please make sure this PR triggers the repository's CI and resolve any workflow problems. DripTide will keep watching and review the change when checks pass. |
Merge Conflict — Action NeededThis pull request has merge conflicts with the base branch ( What to do: update your branch by merging or rebasing against |
CI checks neededNo checks are visible on this commit. Please make sure this PR triggers the repository's CI and resolve any workflow problems. DripTide will keep watching and review the change when checks pass. |
Merge Conflict — Action NeededThis pull request has merge conflicts with the base branch ( What to do: update your branch by merging or rebasing against |
CI checks neededNo checks are visible on this commit. Please make sure this PR triggers the repository's CI and resolve any workflow problems. DripTide will keep watching and review the change when checks pass. |
Merge Conflict — Action NeededThis pull request has merge conflicts with the base branch ( What to do: update your branch by merging or rebasing against |
Summary & Motivation
The
astroid-interfacescrate is the contract interface definition layer for the Astroid protocol: every member contract (registry, wallet, multisig, proposal, treasury, budget, policy, escrow) and every client SDK (TypeScript SDK, API, dashboard) must interpret failure modes identically. Per the contribution guidelines, every error is a named variant (INSUFFICIENT_FUNDS,POLICY_DENIED,BUDGET_EXCEEDED, …) annotated with#[contracterror], carrying an explicitu32discriminant that is part of the public ABI.This PR completes the interfaces-crate side of that contract:
astroid_interfaces::Error, so SDK consumers and cross-contract clients depend on the interfaces crate alone for the error type used by every trait signature (RegistryInterface,PolicyInterface,BudgetInterface,TelemetryInterface, …).ScVal::Error(ScError::Contract(code))with its exact discriminant, and the generatedScSpecEntry::UdtErrorEnumV0contract spec (what SDK binding generators consume) is validated for one case per variant with exact names and codes.Error → soroban_sdk::Error,Error → InvokeError, and inverseTryFromround-trips across all 50 live variants, plus a fail-closed check proving unknown contract codes never fabricate a variant.No numeric codes were added, removed, or reordered by this PR — it is ABI-neutral.
What Changed
interfaces/src/lib.rspub use crate::errors::Error;— crate-root re-export souse astroid_interfaces::Error;resolvesinterfaces/src/errors.rsALL_VARIANTStablecontracts/budget/src/test.rsclippy --all-targetslint fix (needless borrow)contracts/multisig/src/test.rsclippy --all-targetslint fixes (unused variable, needless borrows)Design Decisions
astroid-shared::errors. The PR checklist requires error codes to be added toshared/errors.rs; the interfaces crate re-exports it rather than redefining it. There is exactly one enum in the protocol — zero possibility of ABI drift between what contracts raise and what SDKs decode.ALL_VARIANTSconst table feeds the stability, uniqueness, spec-coverage, serialization and conversion tests. A future error variant needs exactly one table entry to be fully covered — reviewer-friendly and regression-proof.main. The branch was rebased onto current main mid-development; the test table now reflects the enum as it stands today:AssetNotWhitelisted = 25was retired upstream (consolidated intoAssetNotAuthorized = 43, slot never reused — asserted by the uniqueness test) andTreasuryPaused = 85is covered.Test Plan & Results
The ten tests in
interfaces/src/errors.rs:error_discriminants_are_stableu32code (public ABI)error_discriminants_are_uniqueerror_implements_required_traitsCopy + Clone + Debug + Eq + PartialEq(#[contracterror]requirement)error_as_contract_returnResult<_, Error>in contract entrypointserror_from_discriminantu32code back to its varianterror_spec_xdr_deserializes_with_all_variantsUdtErrorEnumV0with exact names + codes for SDK binding generatorserror_converts_into_sdk_error_preserving_codeInto<soroban_sdk::Error>preserves type + code (whatpanic_with_error!raises)error_try_from_sdk_error_round_tripsTryFrom<sdk::Error>andTryFrom<InvokeError>round-trip; unknown codes fail closederror_scval_serialization_round_tripsScVal::Error(ScError::Contract(code))representation, decoded back to the exact variantcrate_root_reexport_is_the_canonical_errorastroid_interfaces::Erroris the identical type every contract returnsCommands run (all passing):
Acceptance Criteria
u32discriminants available viainterfaces/src/errorsmodule)sdk::Error,InvokeError,TryFromround-trips)cargo buildABI & Compatibility Notes
astroid_shared::errors::Error— the identical type now also reachable asastroid_interfaces::Error. No contract code paths change.lib.rsare untouched.Reviewer Notes
pub useline; everything else is test coverage.stellar contract build,cargo test --workspace,cargo fmt --check,cargo clippy --workspace -- -D warnings— all verified locally.Closes #205