From a4873716957fa7443c9e2e02dbc627380ddd9d68 Mon Sep 17 00:00:00 2001 From: Sergii <1159966+stalniy@users.noreply.github.com> Date: Wed, 3 Jun 2026 11:33:00 +0200 Subject: [PATCH] fix: properly serialize provider audited attributes --- x/audit/keeper/grpc_query.go | 50 ++++++++++++-------- x/audit/keeper/grpc_query_test.go | 78 +++++++++++++++++++++++++++++++ x/audit/keeper/keeper.go | 1 - 3 files changed, 109 insertions(+), 20 deletions(-) diff --git a/x/audit/keeper/grpc_query.go b/x/audit/keeper/grpc_query.go index b7799b16bb..d51dce358c 100644 --- a/x/audit/keeper/grpc_query.go +++ b/x/audit/keeper/grpc_query.go @@ -32,15 +32,19 @@ func (q Querier) AllProvidersAttributes( store := ctx.KVStore(q.skey) - pageRes, err := sdkquery.Paginate(store, req.Pagination, func(_ []byte, value []byte) error { - var provider types.AuditedProvider + pageRes, err := sdkquery.Paginate(store, req.Pagination, func(key []byte, value []byte) error { + id := ParseIDFromKey(key) - err := q.cdc.Unmarshal(value, &provider) - if err != nil { + var sVal types.AuditedAttributesStore + if err := q.cdc.Unmarshal(value, &sVal); err != nil { return err } - providers = append(providers, provider) + providers = append(providers, types.AuditedProvider{ + Owner: id.Owner.String(), + Auditor: id.Auditor.String(), + Attributes: sVal.Attributes, + }) return nil }) if err != nil { @@ -121,28 +125,36 @@ func (q Querier) AuditorAttributes( return nil, status.Error(codes.InvalidArgument, "empty request") } + auditor, err := sdk.AccAddressFromBech32(req.Auditor) + if err != nil { + return nil, types.ErrInvalidAddress + } + var providers types.AuditedProviders ctx := sdk.UnwrapSDKContext(c) - store := ctx.KVStore(q.skey) - pageRes, err := sdkquery.Paginate(store, req.Pagination, func(_ []byte, value []byte) error { - var provider types.AuditedProvider - - err := q.cdc.Unmarshal(value, &provider) - if err != nil { - return err + pageRes, err := sdkquery.FilteredPaginate(store, req.Pagination, func(key []byte, value []byte, accumulate bool) (bool, error) { + id := ParseIDFromKey(key) + if !id.Auditor.Equals(auditor) { + return false, nil } - - providers = append(providers, provider) - return nil + if accumulate { + var sVal types.AuditedAttributesStore + if err := q.cdc.Unmarshal(value, &sVal); err != nil { + return false, err + } + providers = append(providers, types.AuditedProvider{ + Owner: id.Owner.String(), + Auditor: id.Auditor.String(), + Attributes: sVal.Attributes, + }) + } + return true, nil }) if err != nil { return nil, status.Error(codes.Internal, err.Error()) } - return &types.QueryProvidersResponse{ - Providers: providers, - Pagination: pageRes, - }, nil + return &types.QueryProvidersResponse{Providers: providers, Pagination: pageRes}, nil } diff --git a/x/audit/keeper/grpc_query_test.go b/x/audit/keeper/grpc_query_test.go index 069b2b796e..0d9db6cdcf 100644 --- a/x/audit/keeper/grpc_query_test.go +++ b/x/audit/keeper/grpc_query_test.go @@ -121,6 +121,11 @@ func TestGRPCQueryProviders(t *testing.T) { err = suite.keeper.CreateOrUpdateProviderAttributes(suite.ctx, id2, provider2.Attributes) require.NoError(t, err) + expByOwner := map[string]types.AuditedProvider{ + provider.Owner: provider, + provider2.Owner: provider2, + } + var req *types.QueryAllProvidersAttributesRequest testCases := []struct { @@ -159,6 +164,79 @@ func TestGRPCQueryProviders(t *testing.T) { require.NoError(t, err) require.NotNil(t, res) require.Equal(t, tc.expLen, len(res.Providers)) + + for _, got := range res.Providers { + // Regression guard: Owner must be a valid bech32 address, not raw + // protobuf bytes from a mis-unmarshaled value. + _, err := sdk.AccAddressFromBech32(got.Owner) + require.NoErrorf(t, err, "owner %q is not a valid bech32 address", got.Owner) + + exp, ok := expByOwner[got.Owner] + require.Truef(t, ok, "unexpected owner %q", got.Owner) + require.Equal(t, exp.Auditor, got.Auditor) + require.Equal(t, exp.Attributes, got.Attributes) + } }) } } + +func TestGRPCQueryAuditorAttributes(t *testing.T) { + suite := setupTest(t) + + // Two providers under the same auditor. + auditor := testutil.AccAddress(t) + + _, provider1 := testutil.AuditedProvider(t) + id1 := types.ProviderID{Owner: testutil.AccAddress(t), Auditor: auditor} + provider1.Owner = id1.Owner.String() + provider1.Auditor = id1.Auditor.String() + err := suite.keeper.CreateOrUpdateProviderAttributes(suite.ctx, id1, provider1.Attributes) + require.NoError(t, err) + + _, provider2 := testutil.AuditedProvider(t) + id2 := types.ProviderID{Owner: testutil.AccAddress(t), Auditor: auditor} + provider2.Owner = id2.Owner.String() + provider2.Auditor = id2.Auditor.String() + err = suite.keeper.CreateOrUpdateProviderAttributes(suite.ctx, id2, provider2.Attributes) + require.NoError(t, err) + + // A third provider under a different auditor, which must be filtered out. + idOther, providerOther := testutil.AuditedProvider(t) + err = suite.keeper.CreateOrUpdateProviderAttributes(suite.ctx, idOther, providerOther.Attributes) + require.NoError(t, err) + + res, err := suite.queryClient.AuditorAttributes(suite.ctx, &types.QueryAuditorAttributesRequest{ + Auditor: auditor.String(), + }) + require.NoError(t, err) + require.NotNil(t, res) + require.Len(t, res.Providers, 2) + + expByOwner := map[string]types.AuditedProvider{ + provider1.Owner: provider1, + provider2.Owner: provider2, + } + + for _, got := range res.Providers { + require.Equal(t, auditor.String(), got.Auditor) + exp, ok := expByOwner[got.Owner] + require.Truef(t, ok, "unexpected owner %q returned for auditor", got.Owner) + require.Equal(t, exp.Attributes, got.Attributes) + } +} + +func TestGRPCQueryProviderAttributes(t *testing.T) { + suite := setupTest(t) + + id, provider := testutil.AuditedProvider(t) + err := suite.keeper.CreateOrUpdateProviderAttributes(suite.ctx, id, provider.Attributes) + require.NoError(t, err) + + res, err := suite.queryClient.ProviderAttributes(suite.ctx, &types.QueryProviderAttributesRequest{ + Owner: provider.Owner, + }) + require.NoError(t, err) + require.NotNil(t, res) + require.Len(t, res.Providers, 1) + require.Equal(t, provider, res.Providers[0]) +} diff --git a/x/audit/keeper/keeper.go b/x/audit/keeper/keeper.go index a90486c7ef..b5cd309296 100644 --- a/x/audit/keeper/keeper.go +++ b/x/audit/keeper/keeper.go @@ -261,7 +261,6 @@ func (k Keeper) WithProvider(ctx sdk.Context, id sdk.Address, fn func(types.Audi Auditor: aID.Auditor.String(), Attributes: attr.Attributes, } - k.cdc.MustUnmarshal(iter.Value(), &val) if stop := fn(val); stop { break }