package keeper import ( "context" "github.com/cerc-io/laconicd/x/nameservice/types" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) // BondIDAttributeName denotes the record bond ID. const BondIDAttributeName = "bondId" // ExpiryTimeAttributeName denotes the record expiry time. const ExpiryTimeAttributeName = "expiryTime" type Querier struct { Keeper } var _ types.QueryServer = Querier{} func (q Querier) Params(c context.Context, _ *types.QueryParamsRequest) (*types.QueryParamsResponse, error) { ctx := sdk.UnwrapSDKContext(c) params := q.Keeper.GetParams(ctx) return &types.QueryParamsResponse{Params: ¶ms}, nil } func (q Querier) ListRecords(c context.Context, req *types.QueryListRecordsRequest) (*types.QueryListRecordsResponse, error) { ctx := sdk.UnwrapSDKContext(c) attributes := req.GetAttributes() all := req.GetAll() records := []types.Record{} if len(attributes) > 0 { records = q.Keeper.MatchRecords(ctx, func(record *types.RecordType) bool { return MatchOnAttributes(record, attributes, all) }) } else { records = q.Keeper.ListRecords(ctx) } return &types.QueryListRecordsResponse{Records: records}, nil } func (q Querier) GetRecord(c context.Context, req *types.QueryRecordByIdRequest) (*types.QueryRecordByIdResponse, error) { ctx := sdk.UnwrapSDKContext(c) id := req.GetId() if !q.Keeper.HasRecord(ctx, id) { return nil, sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, "Record not found.") } record := q.Keeper.GetRecord(ctx, id) return &types.QueryRecordByIdResponse{Record: record}, nil } func (q Querier) GetRecordByBondId(c context.Context, req *types.QueryRecordByBondIdRequest) (*types.QueryRecordByBondIdResponse, error) { ctx := sdk.UnwrapSDKContext(c) records := q.recordKeeper.QueryRecordsByBond(ctx, req.GetId()) return &types.QueryRecordByBondIdResponse{Records: records}, nil } func (q Querier) GetNameServiceModuleBalance(c context.Context, _ *types.GetNameServiceModuleBalanceRequest) (*types.GetNameServiceModuleBalanceResponse, error) { ctx := sdk.UnwrapSDKContext(c) balances := q.Keeper.GetModuleBalances(ctx) return &types.GetNameServiceModuleBalanceResponse{ Balances: balances, }, nil } func (q Querier) ListNameRecords(c context.Context, _ *types.QueryListNameRecordsRequest) (*types.QueryListNameRecordsResponse, error) { ctx := sdk.UnwrapSDKContext(c) nameRecords := q.Keeper.ListNameRecords(ctx) return &types.QueryListNameRecordsResponse{Names: nameRecords}, nil } func (q Querier) Whois(c context.Context, request *types.QueryWhoisRequest) (*types.QueryWhoisResponse, error) { ctx := sdk.UnwrapSDKContext(c) nameAuthority := q.Keeper.GetNameAuthority(ctx, request.GetName()) return &types.QueryWhoisResponse{NameAuthority: nameAuthority}, nil } func (q Querier) LookupCrn(c context.Context, req *types.QueryLookupCrn) (*types.QueryLookupCrnResponse, error) { ctx := sdk.UnwrapSDKContext(c) crn := req.GetCrn() if !q.Keeper.HasNameRecord(ctx, crn) { return nil, sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, "CRN not found.") } nameRecord := q.Keeper.GetNameRecord(ctx, crn) if nameRecord == nil { return nil, sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, "name record not found.") } return &types.QueryLookupCrnResponse{Name: nameRecord}, nil } func (q Querier) ResolveCrn(c context.Context, req *types.QueryResolveCrn) (*types.QueryResolveCrnResponse, error) { ctx := sdk.UnwrapSDKContext(c) crn := req.GetCrn() record := q.Keeper.ResolveCRN(ctx, crn) if record == nil { return nil, sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, "record not found.") } return &types.QueryResolveCrnResponse{Record: record}, nil } func (q Querier) GetRecordExpiryQueue(c context.Context, _ *types.QueryGetRecordExpiryQueue) (*types.QueryGetRecordExpiryQueueResponse, error) { ctx := sdk.UnwrapSDKContext(c) records := q.Keeper.GetRecordExpiryQueue(ctx) return &types.QueryGetRecordExpiryQueueResponse{Records: records}, nil } func (q Querier) GetAuthorityExpiryQueue(c context.Context, _ *types.QueryGetAuthorityExpiryQueue) (*types.QueryGetAuthorityExpiryQueueResponse, error) { ctx := sdk.UnwrapSDKContext(c) authorities := q.Keeper.GetAuthorityExpiryQueue(ctx) return &types.QueryGetAuthorityExpiryQueueResponse{Authorities: authorities}, nil } func matchOnRecordField(record *types.RecordType, attr *types.QueryListRecordsRequest_KeyValueInput) (fieldFound bool, matched bool) { fieldFound = false matched = true switch attr.Key { case BondIDAttributeName: { fieldFound = true if record.BondId != attr.Value.GetString_() { matched = false return } } case ExpiryTimeAttributeName: { fieldFound = true if record.ExpiryTime != attr.Value.GetString_() { matched = false return } } } return } func MatchOnAttributes(record *types.RecordType, attributes []*types.QueryListRecordsRequest_KeyValueInput, all bool) bool { // Filter deleted records. if record.Deleted { return false } // If ONLY named records are requested, check for that condition first. if !all && len(record.Names) == 0 { return false } recAttrs := record.Attributes for _, attr := range attributes { // First try matching on record struct fields. fieldFound, matched := matchOnRecordField(record, attr) if fieldFound { if !matched { return false } continue } recAttrVal, recAttrFound := recAttrs[attr.Key] if !recAttrFound { return false } if attr.Value.Type == "int" { recAttrValInt, ok := recAttrVal.(int) if !ok || int(attr.Value.GetInt()) != recAttrValInt { return false } } if attr.Value.Type == "float" { recAttrValFloat, ok := recAttrVal.(float64) if !ok || attr.Value.GetFloat() != recAttrValFloat { return false } } if attr.Value.Type == "string" { recAttrValString, ok := recAttrVal.(string) if !ok { return false } if attr.Value.GetString_() != recAttrValString { return false } } if attr.Value.Type == "boolean" { recAttrValBool, ok := recAttrVal.(bool) if !ok || attr.Value.GetBoolean() != recAttrValBool { return false } } if attr.Value.Type == "reference" { obj, ok := recAttrVal.(map[string]interface{}) if !ok { // Attr value is not an object. return false } if _, ok := obj["/"].(string); !ok { // Attr value is not a reference. return false } recAttrValRefID := obj["/"].(string) if recAttrValRefID != attr.Value.GetReference().GetId() { return false } } // TODO: Handle arrays. } return true }