Skip to content

Updated ListAssetRequest to include additional filter options #1199

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

itsrachelfish
Copy link

@itsrachelfish itsrachelfish commented Nov 16, 2024

Resolves #876

This PR adds new filter options to the ListAssets RPC call.

  • The ListAssetRequest proto definition was updated to include the new filter options.
  • The fetchRpcAssets function was refactored to accept a AssetQueryFilters argument so that separate arguments don't need to be added for each filter option.
  • The assets store constraintsToDbFilter function was updated to use the new filter options.
  • And the assets.sql file was updated to include a new maxAmount option.

@dstadulis dstadulis added this to the v0.5 (v0.4.2 rename) milestone Nov 17, 2024
@Roasbeef Roasbeef modified the milestones: v0.5 (v0.4.2 rename), v0.6 Nov 19, 2024
@itsrachelfish itsrachelfish force-pushed the listassets-filters branch 4 times, most recently from f31d9f4 to f189364 Compare November 20, 2024 08:56
@coveralls
Copy link

coveralls commented Nov 20, 2024

Pull Request Test Coverage Report for Build 14005124093

Details

  • 23 of 107 (21.5%) changed or added relevant lines in 4 files are covered.
  • 43 unchanged lines in 5 files lost coverage.
  • Overall coverage decreased (-0.05%) to 27.876%

Changes Missing Coverage Covered Lines Changed/Added Lines %
tapdb/assets_store.go 22 30 73.33%
taprpc/taprootassets.pb.go 0 25 0.0%
rpcserver.go 0 51 0.0%
Files with Coverage Reduction New Missed Lines %
address/address.go 2 67.47%
address/mock.go 2 88.24%
tapgarden/caretaker.go 3 68.15%
asset/mock.go 10 63.7%
asset/asset.go 26 48.59%
Totals Coverage Status
Change from base Build 13840646748: -0.05%
Covered Lines: 25364
Relevant Lines: 90990

💛 - Coveralls

@GeorgeTsagk GeorgeTsagk self-requested a review November 20, 2024 10:16
@itsrachelfish itsrachelfish force-pushed the listassets-filters branch 2 times, most recently from 6abd778 to 3c0141b Compare November 20, 2024 10:23
Copy link
Member

@GeorgeTsagk GeorgeTsagk left a comment

Choose a reason for hiding this comment

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

looking good!
it's in the right direction 💯

@itsrachelfish itsrachelfish force-pushed the listassets-filters branch 7 times, most recently from 13eabd1 to 241d98d Compare November 27, 2024 11:47
@itsrachelfish itsrachelfish force-pushed the listassets-filters branch 5 times, most recently from f5d1985 to 9c7b7e9 Compare December 4, 2024 07:29
@itsrachelfish itsrachelfish changed the title [WIP] Updated ListAssetRequest to include additional filter options Updated ListAssetRequest to include additional filter options Dec 7, 2024
@itsrachelfish itsrachelfish marked this pull request as ready for review December 7, 2024 10:54
Copy link
Member

@GeorgeTsagk GeorgeTsagk left a comment

Choose a reason for hiding this comment

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

lots of improvements! ⬆️
I have one comment on the types of filters

We'll also need that unit test coverage ✔️

Int64: int64(query.MaxAmt),
Valid: true,
}
} else {
Copy link
Member

Choose a reason for hiding this comment

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

this whole block is not needed, you can just leave query.MaxAmt initialized to default values (Valid: false)

Copy link
Member

Choose a reason for hiding this comment

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

^ can just remove whole else block

@@ -980,6 +1008,10 @@ type AssetQueryFilters struct {
// MinAnchorHeight is the minimum block height the asset's anchor tx
// must have been confirmed at.
MinAnchorHeight int32

ScriptKeyID *int64
Copy link
Member

Choose a reason for hiding this comment

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

missing godocs (see MinAnchorHeight above)

if query.MinAnchorHeight != 0 {
assetFilter.MinAnchorHeight = sqlInt32(
query.MinAnchorHeight,
)
}

if query.ScriptKeyID != nil {
Copy link
Member

Choose a reason for hiding this comment

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

we can't really have user-facing arguments that reference database IDs

the ScriptKeyID is the DB identifier for a script key and there's no possible way a user could (...easily) get their hands on one of them in order to filter the assets

Instead we could have *AssetQueryFilters expose scriptKey []byte and anchorOutpoint []byte filters, which the user can easily acquire, then on this point in the code we could map these values to the unique db ID that the underlying layer requires for filtering (that is QueryAssetFilters struct)

Copy link
Member

Choose a reason for hiding this comment

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

if you add some tests with the current way things work, you'll see that when you'll try to query a specific script key you'll have trouble finding the ID to filter by

@Roasbeef
Copy link
Member

I think this function can help resolve the issue w.r.t getting the internal ID, you can just specify all the normal bytes (script key, anchor point, etc):

// specificAssetFilter maps the given asset parameters to the set of filters
// we use in the SQL queries.
func (a *AssetStore) specificAssetFilter(id asset.ID, anchorPoint wire.OutPoint,
groupKey *asset.GroupKey,
scriptKey *asset.ScriptKey) (QueryAssetFilters, error) {
anchorPointBytes, err := encodeOutpoint(anchorPoint)
if err != nil {
return QueryAssetFilters{}, fmt.Errorf("unable to encode "+
"outpoint: %w", err)
}
filter := QueryAssetFilters{
AssetIDFilter: id[:],
AnchorPoint: anchorPointBytes,
Now: sql.NullTime{
Time: a.clock.Now().UTC(),
Valid: true,
},
}
if groupKey != nil {
key := groupKey.GroupPubKey
filter.KeyGroupFilter = key.SerializeCompressed()
}
if scriptKey != nil {
key := scriptKey.PubKey
filter.TweakedScriptKey = key.SerializeCompressed()
}
return filter, nil
}

@itsrachelfish itsrachelfish force-pushed the listassets-filters branch 3 times, most recently from ccaf4e4 to ffa733e Compare December 20, 2024 21:53
@itsrachelfish itsrachelfish force-pushed the listassets-filters branch 3 times, most recently from c74c44a to 8b0d382 Compare February 25, 2025 22:58
@itsrachelfish
Copy link
Author

@GeorgeTsagk @guggero I updated the code to filter assets based on the tweaked script key instead of the internal script key ID. I ran into some weird issues with the automated tests, for some reason I was unable to filter the 10th asset:

assetGen:    assetGen.assetGens[9],
anchorPoint: assetGen.anchorPoints[4],
amt:         777,
scriptKey:   scriptKeyWithScript,

Oli said this might have something to do with an underlying issue with the specific anchor point or asset generation, but I'm not sure why this particular asset is "cursed" 😅

I worked around the issue by adding a script key to the 3rd asset and was able to filter it as expected.

@guggero guggero self-requested a review March 10, 2025 22:06
Copy link
Member

@GeorgeTsagk GeorgeTsagk left a comment

Choose a reason for hiding this comment

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

super close 💯
mostly styling related comments

should also add the filter options to the cmd command but since they weren't there in the first place this can be done in a different PR

Int64: int64(query.MaxAmt),
Valid: true,
}
} else {
Copy link
Member

Choose a reason for hiding this comment

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

^ can just remove whole else block

@itsrachelfish itsrachelfish force-pushed the listassets-filters branch 2 times, most recently from 517d54a to 402d754 Compare March 13, 2025 21:53
@itsrachelfish itsrachelfish force-pushed the listassets-filters branch 2 times, most recently from a2be556 to 402d754 Compare March 22, 2025 04:18
Copy link
Member

@guggero guggero left a comment

Choose a reason for hiding this comment

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

Almost there.

@@ -873,12 +873,38 @@ func (a *AssetStore) constraintsToDbFilter(
Valid: true,
}
}

if query.MaxAmt != 0 {
assetFilter.MaxAmt = sql.NullInt64{
Copy link
Member

Choose a reason for hiding this comment

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

nit: can use sqlInt64(query.MaxAmt) (and change it above for the MinAmt as well).

if err != nil {
return QueryAssetFilters{}, fmt.Errorf(
"unable to encode outpoint: %w", err,
)
Copy link
Member

Choose a reason for hiding this comment

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

nit: calls to Errorf() can have the closing parenthesis on the same line as the arguments (see formatting exception in the formatting doc).

nil, groupKey, nil, false,
)
if err != nil {
return nil, fmt.Errorf(
Copy link
Member

Choose a reason for hiding this comment

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

nit: inconsistent with other formatting. Can be:

			return nil, fmt.Errorf("error creating asset "+
				"specifier: %w", err)

CoinSelectType: tapsend.ScriptTreesAllowed,
}

if req.GroupKey != nil {
Copy link
Member

Choose a reason for hiding this comment

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

Should check the length here instead, which asserts nil as well as an empty slice.

}

if req.GroupKey != nil {
groupKey, err := btcec.ParsePubKey(req.GroupKey[:])
Copy link
Member

Choose a reason for hiding this comment

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

req.GroupKey is already a slice, no need to use slice operator.

}

// Construct an asset specifier using the requested group key.
groupSpecifier, err := asset.NewSpecifier(
Copy link
Member

Choose a reason for hiding this comment

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

Use NewSpecifierFromGroupKey instead.

CommitmentConstraints: constraints,
}

if req.ScriptKey != nil {
Copy link
Member

Choose a reason for hiding this comment

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

Same here, should be length check, not nil check.

constraints := tapfreighter.CommitmentConstraints{
MinAmt: req.MinAmount,
MaxAmt: req.MaxAmount,
CoinSelectType: tapsend.ScriptTreesAllowed,
Copy link
Member

Choose a reason for hiding this comment

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

Should probably use tapsend.DefaultCoinSelectType here.

@lightninglabs-deploy
Copy link

@GeorgeTsagk: review reminder
@itsrachelfish, remember to re-request review from reviewers when ready

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: 🏗 In progress
Development

Successfully merging this pull request may close these issues.

[feature]: Add filters to ListAssets
7 participants