Skip to content

all: Store SAC, trustline, and native balances in database#464

Closed
Copilot wants to merge 1 commit intostore-sep41-balancefrom
copilot/sub-pr-454-again
Closed

all: Store SAC, trustline, and native balances in database#464
Copilot wants to merge 1 commit intostore-sep41-balancefrom
copilot/sub-pr-454-again

Conversation

Copy link

Copilot AI commented Jan 16, 2026

What

Store SAC balances, trustline balances, and native XLM balances in PostgreSQL tables during ingestion instead of fetching via RPC calls during GraphQL queries.

Why

Eliminates expensive RPC calls for balance queries. Enables scalable balance serving by reading from local database. Provides foundation for real-time balance updates via live ingestion.

Key Changes

Database Schema

  • sac_balances - SAC balance state for contract addresses (C...)
  • trustline_balances - Classic trustline state (balance, limits, liabilities, flags)
  • native_balances - XLM balance with minimum balance and liabilities
  • account_contract_tokens - Junction table for account→contract mappings

Indexer

  • SACBalancesProcessor - Extracts SAC balance changes from contract data entries (["Balance", holder] key pattern)
  • Map-based buffer deduplication - Changed from slice to map for accountChanges, trustlineChanges, sacBalanceChanges
    • Keys: (AccountID, TrustlineID), (AccountID, ContractID), AccountID
    • Keeps latest change per key (highest OperationID)
    • Detects ADD→REMOVE no-ops within same ledger

Services

  • token_ingestion.go (renamed from account_tokens.go) - Unified balance processing
  • Checkpoint population streams all balance types to DB in batches
  • ProcessTokenChanges signature: accepts map[string]types.AccountChange (pre-deduplicated)

GraphQL

  • BalanceReader interface abstracts balance data access
  • Resolvers read from DB tables
  • Added to NativeBalance: minimumBalance, buyingLiabilities, sellingLiabilities, lastModifiedLedger

Balance Entry Processing

// SAC balances extracted from contract data with this structure:
// Key: ScVal::Vec([ScVal::Symbol("Balance"), ScVal::Address(holder)])
// Value: ScVal::Map({amount: i128, authorized: bool, clawback: bool})

// Only contract addresses (C...) stored as SAC balances
// G-addresses use trustlines table instead

Known limitations

Requires checkpoint processing to populate tables before serving queries. Migration must complete before deployment.

Issue that this PR addresses

N/A

Checklist

PR Structure

  • It is not possible to break this PR down into smaller PRs.
  • This PR does not mix refactoring changes with feature changes.
  • This PR's title starts with name of package that is most changed in the PR, or all if the changes are broad or impact many packages.

Thoroughness

  • This PR adds tests for the new functionality or fixes.
  • All updated queries have been tested (refer to this check if the data set returned by the updated query is expected to be same as the original one).

Release

  • This is not a breaking change.
  • This is ready to be tested in development.
  • The new functionality is gated with a feature flag if this is not ready for production.

💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI changed the title [WIP] Process SAC balance entry changes and store SAC balances all: Store SAC, trustline, and native balances in database Jan 16, 2026
Copilot AI requested a review from aditya1702 January 16, 2026 21:21
@aditya1702 aditya1702 closed this Jan 16, 2026
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