Skip to content

taprpc+tapdb: add GenesisInfo to AssetGroupBalance in ListBalances#2130

Open
kaldun-tech wants to merge 1 commit into
lightninglabs:mainfrom
kaldun-tech:taprpc-add-GenesisInfo-AssetGroupBalance-ListBalancesResponse
Open

taprpc+tapdb: add GenesisInfo to AssetGroupBalance in ListBalances#2130
kaldun-tech wants to merge 1 commit into
lightninglabs:mainfrom
kaldun-tech:taprpc-add-GenesisInfo-AssetGroupBalance-ListBalancesResponse

Conversation

@kaldun-tech
Copy link
Copy Markdown
Contributor

@kaldun-tech kaldun-tech commented May 13, 2026

Add GenesisInfo and DecimalDisplay fields to AssetGroupBalance in the ListBalances RPC response when using group_by=group_key mode.

Previously, AssetGroupBalance only contained group_key and balance, making it impossible for clients to display asset metadata (name, type, decimal display) alongside grouped balances without additional RPC calls.

Changes

  • Proto: Added asset_genesis (field 3) and decimal_display (field 4) to AssetGroupBalance message
  • SQL: Modified QueryAssetBalancesByGroup to join genesis_info_view and return genesis data for a representative issuance per group
  • DB Store: Extended AssetGroupBalance struct with genesis fields and updated query result mapping
  • RPC Server: Populated new fields in listBalancesByGroupKey, including DecimalDisplay lookup via DecDisplayForAssetID

Design Notes

  • The representative genesis per group is selected using MIN(gen_asset_id), which gives the earliest-inserted genesis. For locally-minted assets, this is the group anchor. For fungible assets, all tranches share the same name/type, so any genesis provides correct metadata.
  • ErrAssetMetaNotFound leaves DecimalDisplay unset (asset has no meta); other errors are escalated to the caller.
  • Ungrouped assets are intentionally excluded from QueryAssetBalancesByGroup results (use group_by=asset_id mode for those).

Test Coverage Gaps

  1. Error handling paths in RPC layer: The ErrAssetMetaNotFound and error escalation paths in listBalancesByGroupKey are not directly unit tested. This would require mocking AddrBook.DecDisplayForAssetID.

  2. Received grouped assets without local anchor: Edge case where we receive a grouped asset but don't have the anchor locally. The new query should still work (joins through asset_groups.genesis_point_id), but this isn't explicitly tested.

Test Plan

  • make unit pkg=tapdb - verify DB layer changes
  • make unit pkg=rpcserver - verify RPC marshaling
  • Manual test run via make itest icase=minting_multi_asset_groups
  • tapcli assets balance --by-group returns genesis info
  • Manual test: JSON/REST response includes new fields

Fixes issue #2066

@gemini-code-assist
Copy link
Copy Markdown

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request enhances the 'ListBalances' RPC functionality by including comprehensive metadata for grouped assets. By adding genesis information and decimal display settings to the 'AssetGroupBalance' response, clients can now display asset details directly without requiring additional API calls. The changes involve updates to the protocol buffers, database query logic, and the RPC server implementation to populate these new fields efficiently.

Highlights

  • RPC Response Enhancement: Added 'asset_genesis' and 'decimal_display' fields to the 'AssetGroupBalance' message in the 'ListBalances' RPC response to provide necessary asset metadata.
  • Database Query Optimization: Updated 'QueryAssetBalancesByGroup' to join with 'genesis_info_view', allowing the retrieval of representative genesis information for each asset group.
  • Data Struct Updates: Extended the 'AssetGroupBalance' struct in the database layer to include genesis fields, ensuring consistent data mapping from the SQL query results.
New Features

🧠 You can now enable Memory (public preview) to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize the Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counterproductive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request enhances the ListBalances RPC by including representative genesis information and decimal display metadata for asset groups. The changes involve updating the database queries to select anchor genesis data, extending the AssetGroupBalance structures in both the database and RPC layers, and populating these new fields in the RPC server. Feedback was provided regarding a potential N+1 query performance issue when fetching decimal displays and a requirement to use structured logging for debug messages as per the repository style guide.

Comment thread rpcserver/rpcserver.go
Comment thread rpcserver/rpcserver.go Outdated
@kaldun-tech kaldun-tech force-pushed the taprpc-add-GenesisInfo-AssetGroupBalance-ListBalancesResponse branch 2 times, most recently from 2b0f3f4 to 48f4267 Compare May 13, 2026 15:47
@kaldun-tech
Copy link
Copy Markdown
Contributor Author

I believe these CI failures are flakes. @claude please code review and investigate whether the failed CI is due to code changes or flakes

@kaldun-tech kaldun-tech marked this pull request as ready for review May 13, 2026 19:13
@kaldun-tech
Copy link
Copy Markdown
Contributor Author

@jtobin @darioAnongba Please re-run the failed CI jobs. My investigation is that the failures were due to flakes but let me know if you want me to look into anything on my end

@darioAnongba darioAnongba self-requested a review May 22, 2026 13:55
Comment thread rpcserver/rpcserver.go Outdated
Comment on lines 1510 to 1523
if err == nil {
groupBalance.DecimalDisplay = fn.MapOptionZ(
decDisplay,
func(d uint32) *taprpc.DecimalDisplay {
return &taprpc.DecimalDisplay{
DecimalDisplay: d,
}
},
)
} else {
rpcsLog.DebugS(ctx, "Failed to fetch decimal display",
btclog.Fmt("asset_id", "%x", balance.ID[:]),
"error", err)
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We can avoid silently logging debug and escalate instead.

Suggested change
if err == nil {
groupBalance.DecimalDisplay = fn.MapOptionZ(
decDisplay,
func(d uint32) *taprpc.DecimalDisplay {
return &taprpc.DecimalDisplay{
DecimalDisplay: d,
}
},
)
} else {
rpcsLog.DebugS(ctx, "Failed to fetch decimal display",
btclog.Fmt("asset_id", "%x", balance.ID[:]),
"error", err)
}
switch {
case errors.Is(err, address.ErrAssetMetaNotFound):
// Asset legitimately has no meta — leave DecimalDisplay unset.
case err != nil:
return nil, fmt.Errorf("unable to fetch decimal display "+
"for asset %x: %w", balance.ID[:], err)
default:
groupBalance.DecimalDisplay = fn.MapOptionZ(
decDisplay,
func(d uint32) *taprpc.DecimalDisplay {
return &taprpc.DecimalDisplay{DecimalDisplay: d}
},
)
}

Comment thread tapdb/sqlc/queries/assets.sql Outdated
-- works for locally-minted assets where the anchor is inserted first.
SELECT
tweaked_group_key,
MIN(gen_asset_id) as anchor_gen_id
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

gen_asset_id is a local-DB primary key reflecting local insertion order, not protocol-level ordering or any canonical anchor. The canonical anchor is stored explicitly in asset_groups.genesis_point_id

A fix is to join through asset_groups.genesis_point_id to resolve the actual anchor gen_asset_id. The existing FetchGroupByGroupKey pattern (ORDER BY witness_id LIMIT 1) already does this.

@github-project-automation github-project-automation Bot moved this from 🆕 New to 👀 In review in Taproot-Assets Project Board May 26, 2026
@kaldun-tech
Copy link
Copy Markdown
Contributor Author

Hey @darioAnongba thanks for the feedback. I'm making a few changes:

  1. SQL Query (assets.sql): Changing from MIN(gen_asset_id) to joining through asset_groups.genesis_point_id for canonical anchor selection.
  2. Error Handling (rpcserver.go): Changing from silent debug logging to proper error handling - ErrAssetMetaNotFound leaves DecimalDisplay unset, other errors are escalated.
  3. Unit Tests (assets_store_test.go): Adding assertions to verify genesis info fields match expected anchor genesis for each group.

Added GenesisInfo and DecimalDisplay fields to the
AssetGroupBalance message, making the group_by=group_key mode of
ListBalances useful for clients that need asset metadata alongside
balances.

The SQL query was modified to join genesis_info_view and return genesis
data for a representative issuance per group (selected via MIN to get
the earliest-inserted genesis, which is the anchor for locally-minted
assets).

Additional tests in asset_store_test for new failure cases.

Fixes lightninglabs#2066.

Signed-off-by: kaldun-tech <tsmereka@protonmail.com>
@kaldun-tech kaldun-tech force-pushed the taprpc-add-GenesisInfo-AssetGroupBalance-ListBalancesResponse branch from 48f4267 to 44d12a0 Compare May 27, 2026 15:48
@kaldun-tech
Copy link
Copy Markdown
Contributor Author

@darioAnongba Pushed my changes

  1. SQL query now joins through asset_groups.genesis_point_id for canonical anchor selection
  2. Error handling escalates non-ErrAssetMetaNotFound errors instead of silent logging
  3. Added DB layer test assertions verifying genesis info matches the expected anchor

@kaldun-tech
Copy link
Copy Markdown
Contributor Author

kaldun-tech commented May 27, 2026

Investigated the CI failure. Copilot & Claude pointed me at PR #2133 but this is not yet merged which indicates the failure is due to flakiness. Sergey's changes in PR #2060 may correct this.

EDIT: Second failure today that seems to be caused by issue #2120 and fixed by PR #2132. Will investigate

@lightninglabs-deploy
Copy link
Copy Markdown

@kaldun-tech, remember to re-request review from reviewers when ready

@kaldun-tech kaldun-tech requested a review from darioAnongba June 3, 2026 19:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: 👀 In review

Development

Successfully merging this pull request may close these issues.

3 participants