Skip to content

feat(server): implement /acceptance/checkNote endpoint (#51) - #70

Open
ocakciomursel-pixel wants to merge 1 commit into
BetterMoneyLabs:masterfrom
ocakciomursel-pixel:feat/issue-51-acceptance-check-note
Open

ocakciomursel-pixel wants to merge 1 commit into
BetterMoneyLabs:masterfrom
ocakciomursel-pixel:feat/issue-51-acceptance-check-note

Conversation

@ocakciomursel-pixel

Copy link
Copy Markdown

Fixes #51

Summary

Implements POST /api/v1/acceptance/checkNote in chaincash_server so callers can submit a JSON-encoded ChainCash note and check whether the server accepts it under its configured [acceptance] predicates (Whitelist, Blacklist, Collateral, and recursive Or), returning {"accepted": true|false}.

Key Design Details

  1. Supported JSON Note Formats

    • Wallet / Store NoteWithHistory JSON (exact round-trip output of GET /api/v1/notes/wallet and GET /api/v1/notes/byPubkey/:pubkey).
    • Raw Ergo ErgoBox JSON (validated via chaincash_offchain::boxes::Note::from_box, enriching commitment history automatically when the box is already indexed in ChainCashStore).
    • ErgoBox + Explicit Ownership History JSON ({"ergo_box": ..., "history": [...]} or {"box": ..., "history": [...]}): validates the note box contract/registers, reconstructs NoteHistory (supporting both 65-byte hex and byte-array Schnorr signatures), verifies the reconstructed AVL+ digest matches register R4, and cryptographically verifies every reserve signature against blake2b256(note_id_bytes || amount_be_bytes) when the reserve owner pubkey is known.
    • Direct NoteContext JSON ({"owner", "issuer", "nanoerg", "liabilities"}).
    • Malformed payloads, non-note Ergo boxes, mismatched R4 AVL digests, or invalid reserve signatures return 400 Bad Request.
  2. Gold-to-NanoErg Valuation & Monotone Oracle Short-Circuiting

    • Note token amounts represent milligrams of gold (gold_amount_mg), whereas reserve values are stored in nanoErg.
    • When evaluating Collateral predicates, note and liability amounts are converted to nanoErg using either a stored Denomination row (when denomination_id is present) or the ChainCash Gold Oracle box (R4 / 1_000_000 nanoErg per mg of gold, matching TransactionService::redeem_note).
    • Because all acceptance predicates (Whitelist, Blacklist, Collateral, Or) are monotone with respect to collateral backing, checkNote first evaluates predicates against a zero-collateral provider and short-circuits immediately when Whitelist / Blacklist / Or branches already accept—avoiding unnecessary Ergo node HTTP calls.
  3. Accurate Collateral Accounting & Split-Change Preservation

    • Aggregates unspent reserves per owner pubkey and sums outstanding note liabilities across all stored notes plus the candidate note.
    • Deduplicates an already-indexed candidate note (by ergo_box_id for ErgoBox payloads, or at most one matching stored row for NoteWithHistory payloads) so stored notes are never double-counted while sibling split-change notes sharing the same note_id token identifier remain properly counted in issuer_note_tally.
    • Hardens Blacklist evaluation so unresolved/empty issuer or historical signer pubkeys cannot falsely pass Issuer or Historical blacklist checks, and fixes a nested SQLite pool checkout in NoteRepository::get_by_box_id.

Verification

  • cargo fmt --all -- --check
  • cargo clippy --all-features
  • cargo test (34 passed, 0 failed — including 10 new end-to-end async acceptance::tests covering wallet JSON round-trip, raw ErgoBox, cryptographic Schnorr signature + R4 AVL verification, Gold Oracle conversion, split-change note accounting, intermediate historical signer collateralization, offline-oracle Or short-circuiting, and 400 Bad Request validation)

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.

/acceptance/checkNote API method

1 participant