refactor: Rename deterministic to module_query_safe (#13305)
This commit is contained in:
@@ -22,7 +22,10 @@ const _ = grpc.SupportPackageIsVersion7
|
||||
//
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
|
||||
type QueryClient interface {
|
||||
// Accounts returns all the existing accounts
|
||||
// Accounts returns all the existing accounts.
|
||||
//
|
||||
// When called from another module, this query might consume a high amount of
|
||||
// gas if the pagination field is incorrectly set.
|
||||
//
|
||||
// Since: cosmos-sdk 0.43
|
||||
Accounts(ctx context.Context, in *QueryAccountsRequest, opts ...grpc.CallOption) (*QueryAccountsResponse, error)
|
||||
@@ -134,7 +137,10 @@ func (c *queryClient) AddressStringToBytes(ctx context.Context, in *AddressStrin
|
||||
// All implementations must embed UnimplementedQueryServer
|
||||
// for forward compatibility
|
||||
type QueryServer interface {
|
||||
// Accounts returns all the existing accounts
|
||||
// Accounts returns all the existing accounts.
|
||||
//
|
||||
// When called from another module, this query might consume a high amount of
|
||||
// gas if the pagination field is incorrectly set.
|
||||
//
|
||||
// Since: cosmos-sdk 0.43
|
||||
Accounts(context.Context, *QueryAccountsRequest) (*QueryAccountsResponse, error)
|
||||
|
||||
@@ -25,15 +25,27 @@ type QueryClient interface {
|
||||
// Balance queries the balance of a single coin for a single account.
|
||||
Balance(ctx context.Context, in *QueryBalanceRequest, opts ...grpc.CallOption) (*QueryBalanceResponse, error)
|
||||
// AllBalances queries the balance of all coins for a single account.
|
||||
//
|
||||
// When called from another module, this query might consume a high amount of
|
||||
// gas if the pagination field is incorrectly set.
|
||||
AllBalances(ctx context.Context, in *QueryAllBalancesRequest, opts ...grpc.CallOption) (*QueryAllBalancesResponse, error)
|
||||
// SpendableBalances queries the spenable balance of all coins for a single
|
||||
// account.
|
||||
//
|
||||
// When called from another module, this query might consume a high amount of
|
||||
// gas if the pagination field is incorrectly set.
|
||||
//
|
||||
// Since: cosmos-sdk 0.46
|
||||
SpendableBalances(ctx context.Context, in *QuerySpendableBalancesRequest, opts ...grpc.CallOption) (*QuerySpendableBalancesResponse, error)
|
||||
// TotalSupply queries the total supply of all coins.
|
||||
//
|
||||
// When called from another module, this query might consume a high amount of
|
||||
// gas if the pagination field is incorrectly set.
|
||||
TotalSupply(ctx context.Context, in *QueryTotalSupplyRequest, opts ...grpc.CallOption) (*QueryTotalSupplyResponse, error)
|
||||
// SupplyOf queries the supply of a single coin.
|
||||
//
|
||||
// When called from another module, this query might consume a high amount of
|
||||
// gas if the pagination field is incorrectly set.
|
||||
SupplyOf(ctx context.Context, in *QuerySupplyOfRequest, opts ...grpc.CallOption) (*QuerySupplyOfResponse, error)
|
||||
// Params queries the parameters of x/bank module.
|
||||
Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error)
|
||||
@@ -45,6 +57,9 @@ type QueryClient interface {
|
||||
// DenomOwners queries for all account addresses that own a particular token
|
||||
// denomination.
|
||||
//
|
||||
// When called from another module, this query might consume a high amount of
|
||||
// gas if the pagination field is incorrectly set.
|
||||
//
|
||||
// Since: cosmos-sdk 0.46
|
||||
DenomOwners(ctx context.Context, in *QueryDenomOwnersRequest, opts ...grpc.CallOption) (*QueryDenomOwnersResponse, error)
|
||||
// SendEnabled queries for SendEnabled entries.
|
||||
@@ -162,15 +177,27 @@ type QueryServer interface {
|
||||
// Balance queries the balance of a single coin for a single account.
|
||||
Balance(context.Context, *QueryBalanceRequest) (*QueryBalanceResponse, error)
|
||||
// AllBalances queries the balance of all coins for a single account.
|
||||
//
|
||||
// When called from another module, this query might consume a high amount of
|
||||
// gas if the pagination field is incorrectly set.
|
||||
AllBalances(context.Context, *QueryAllBalancesRequest) (*QueryAllBalancesResponse, error)
|
||||
// SpendableBalances queries the spenable balance of all coins for a single
|
||||
// account.
|
||||
//
|
||||
// When called from another module, this query might consume a high amount of
|
||||
// gas if the pagination field is incorrectly set.
|
||||
//
|
||||
// Since: cosmos-sdk 0.46
|
||||
SpendableBalances(context.Context, *QuerySpendableBalancesRequest) (*QuerySpendableBalancesResponse, error)
|
||||
// TotalSupply queries the total supply of all coins.
|
||||
//
|
||||
// When called from another module, this query might consume a high amount of
|
||||
// gas if the pagination field is incorrectly set.
|
||||
TotalSupply(context.Context, *QueryTotalSupplyRequest) (*QueryTotalSupplyResponse, error)
|
||||
// SupplyOf queries the supply of a single coin.
|
||||
//
|
||||
// When called from another module, this query might consume a high amount of
|
||||
// gas if the pagination field is incorrectly set.
|
||||
SupplyOf(context.Context, *QuerySupplyOfRequest) (*QuerySupplyOfResponse, error)
|
||||
// Params queries the parameters of x/bank module.
|
||||
Params(context.Context, *QueryParamsRequest) (*QueryParamsResponse, error)
|
||||
@@ -182,6 +209,9 @@ type QueryServer interface {
|
||||
// DenomOwners queries for all account addresses that own a particular token
|
||||
// denomination.
|
||||
//
|
||||
// When called from another module, this query might consume a high amount of
|
||||
// gas if the pagination field is incorrectly set.
|
||||
//
|
||||
// Since: cosmos-sdk 0.46
|
||||
DenomOwners(context.Context, *QueryDenomOwnersRequest) (*QueryDenomOwnersResponse, error)
|
||||
// SendEnabled queries for SendEnabled entries.
|
||||
|
||||
@@ -26,24 +26,39 @@ var file_cosmos_query_v1_query_proto_extTypes = []protoimpl.ExtensionInfo{
|
||||
ExtendedType: (*descriptorpb.MethodOptions)(nil),
|
||||
ExtensionType: (*bool)(nil),
|
||||
Field: 11110001,
|
||||
Name: "cosmos.query.v1.deterministic",
|
||||
Tag: "varint,11110001,opt,name=deterministic",
|
||||
Name: "cosmos.query.v1.module_query_safe",
|
||||
Tag: "varint,11110001,opt,name=module_query_safe",
|
||||
Filename: "cosmos/query/v1/query.proto",
|
||||
},
|
||||
}
|
||||
|
||||
// Extension fields to descriptorpb.MethodOptions.
|
||||
var (
|
||||
// deterministic is set to true when the query is guaranteed to return a
|
||||
// deterministic response. Concretely, it means that the query has been
|
||||
// tested on the SDK to return the exact same response upon multiple calls.
|
||||
// Each of these queries also handles its own gas consumption.
|
||||
// module_query_safe is set to true when the query is safe to be called from
|
||||
// within the state machine, for example from another module's Keeper, via
|
||||
// ADR-033 calls or from CosmWasm contracts.
|
||||
// Concretely, it means that the query is:
|
||||
// 1. deterministic: given a block height, returns the exact same response
|
||||
// upon multiple calls; and doesn't introduce any state-machine-breaking
|
||||
// changes across SDK patch version.
|
||||
// 2. consumes gas correctly.
|
||||
//
|
||||
// When set to true, the query can safely be called from within the state
|
||||
// machine, for example via ADR-033 calls or from CosmWasm contracts.
|
||||
// If you are a module developer and want to add this annotation to one of
|
||||
// your own queries, please make sure that the corresponding query:
|
||||
// 1. is deterministic and won't introduce state-machine-breaking changes
|
||||
// without a coordinated upgrade path,
|
||||
// 2. has its gas tracked, to avoid the attack vector where no gas is
|
||||
// accounted for on potentially high-computation queries.
|
||||
//
|
||||
// optional bool deterministic = 11110001;
|
||||
E_Deterministic = &file_cosmos_query_v1_query_proto_extTypes[0]
|
||||
// For queries that potentially consume a large amount of gas (for example
|
||||
// those with pagination, if the pagination field is incorrectly set), we
|
||||
// also recommend adding Protobuf comments to warn module developers
|
||||
// consuming these queries.
|
||||
//
|
||||
// # When set to true, the query can safely be called
|
||||
//
|
||||
// optional bool module_query_safe = 11110001;
|
||||
E_ModuleQuerySafe = &file_cosmos_query_v1_query_proto_extTypes[0]
|
||||
)
|
||||
|
||||
var File_cosmos_query_v1_query_proto protoreflect.FileDescriptor
|
||||
@@ -54,29 +69,30 @@ var file_cosmos_query_v1_query_proto_rawDesc = []byte{
|
||||
0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x76, 0x31, 0x1a, 0x20,
|
||||
0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f,
|
||||
0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x3a, 0x47, 0x0a, 0x0d, 0x64, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x69, 0x73, 0x74, 0x69,
|
||||
0x63, 0x12, 0x1e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e,
|
||||
0x73, 0x18, 0xf1, 0x8c, 0xa6, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x64, 0x65, 0x74, 0x65,
|
||||
0x72, 0x6d, 0x69, 0x6e, 0x69, 0x73, 0x74, 0x69, 0x63, 0x42, 0xa9, 0x01, 0x0a, 0x13, 0x63, 0x6f,
|
||||
0x6d, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x76,
|
||||
0x31, 0x42, 0x0a, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a,
|
||||
0x28, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x61, 0x70,
|
||||
0x69, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2f, 0x76,
|
||||
0x31, 0x3b, 0x71, 0x75, 0x65, 0x72, 0x79, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x43, 0x51, 0x58, 0xaa,
|
||||
0x02, 0x0f, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56,
|
||||
0x31, 0xca, 0x02, 0x0f, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x51, 0x75, 0x65, 0x72, 0x79,
|
||||
0x5c, 0x56, 0x31, 0xe2, 0x02, 0x1b, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x51, 0x75, 0x65,
|
||||
0x72, 0x79, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74,
|
||||
0x61, 0xea, 0x02, 0x11, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x3a, 0x3a, 0x51, 0x75, 0x65, 0x72,
|
||||
0x79, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x3a, 0x4d, 0x0a, 0x11, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79,
|
||||
0x5f, 0x73, 0x61, 0x66, 0x65, 0x12, 0x1e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x4f, 0x70,
|
||||
0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xf1, 0x8c, 0xa6, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f,
|
||||
0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x61, 0x66, 0x65, 0x42,
|
||||
0xa9, 0x01, 0x0a, 0x13, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x71,
|
||||
0x75, 0x65, 0x72, 0x79, 0x2e, 0x76, 0x31, 0x42, 0x0a, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x28, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b,
|
||||
0x2e, 0x69, 0x6f, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x71,
|
||||
0x75, 0x65, 0x72, 0x79, 0x2f, 0x76, 0x31, 0x3b, 0x71, 0x75, 0x65, 0x72, 0x79, 0x76, 0x31, 0xa2,
|
||||
0x02, 0x03, 0x43, 0x51, 0x58, 0xaa, 0x02, 0x0f, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x51,
|
||||
0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x0f, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73,
|
||||
0x5c, 0x51, 0x75, 0x65, 0x72, 0x79, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x1b, 0x43, 0x6f, 0x73, 0x6d,
|
||||
0x6f, 0x73, 0x5c, 0x51, 0x75, 0x65, 0x72, 0x79, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d,
|
||||
0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x11, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73,
|
||||
0x3a, 0x3a, 0x51, 0x75, 0x65, 0x72, 0x79, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var file_cosmos_query_v1_query_proto_goTypes = []interface{}{
|
||||
(*descriptorpb.MethodOptions)(nil), // 0: google.protobuf.MethodOptions
|
||||
}
|
||||
var file_cosmos_query_v1_query_proto_depIdxs = []int32{
|
||||
0, // 0: cosmos.query.v1.deterministic:extendee -> google.protobuf.MethodOptions
|
||||
0, // 0: cosmos.query.v1.module_query_safe:extendee -> google.protobuf.MethodOptions
|
||||
1, // [1:1] is the sub-list for method output_type
|
||||
1, // [1:1] is the sub-list for method input_type
|
||||
1, // [1:1] is the sub-list for extension type_name
|
||||
|
||||
@@ -23,12 +23,21 @@ const _ = grpc.SupportPackageIsVersion7
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
|
||||
type QueryClient interface {
|
||||
// Validators queries all validators that match the given status.
|
||||
//
|
||||
// When called from another module, this query might consume a high amount of
|
||||
// gas if the pagination field is incorrectly set.
|
||||
Validators(ctx context.Context, in *QueryValidatorsRequest, opts ...grpc.CallOption) (*QueryValidatorsResponse, error)
|
||||
// Validator queries validator info for given validator address.
|
||||
Validator(ctx context.Context, in *QueryValidatorRequest, opts ...grpc.CallOption) (*QueryValidatorResponse, error)
|
||||
// ValidatorDelegations queries delegate info for given validator.
|
||||
//
|
||||
// When called from another module, this query might consume a high amount of
|
||||
// gas if the pagination field is incorrectly set.
|
||||
ValidatorDelegations(ctx context.Context, in *QueryValidatorDelegationsRequest, opts ...grpc.CallOption) (*QueryValidatorDelegationsResponse, error)
|
||||
// ValidatorUnbondingDelegations queries unbonding delegations of a validator.
|
||||
//
|
||||
// When called from another module, this query might consume a high amount of
|
||||
// gas if the pagination field is incorrectly set.
|
||||
ValidatorUnbondingDelegations(ctx context.Context, in *QueryValidatorUnbondingDelegationsRequest, opts ...grpc.CallOption) (*QueryValidatorUnbondingDelegationsResponse, error)
|
||||
// Delegation queries delegate info for given validator delegator pair.
|
||||
Delegation(ctx context.Context, in *QueryDelegationRequest, opts ...grpc.CallOption) (*QueryDelegationResponse, error)
|
||||
@@ -36,14 +45,26 @@ type QueryClient interface {
|
||||
// pair.
|
||||
UnbondingDelegation(ctx context.Context, in *QueryUnbondingDelegationRequest, opts ...grpc.CallOption) (*QueryUnbondingDelegationResponse, error)
|
||||
// DelegatorDelegations queries all delegations of a given delegator address.
|
||||
//
|
||||
// When called from another module, this query might consume a high amount of
|
||||
// gas if the pagination field is incorrectly set.
|
||||
DelegatorDelegations(ctx context.Context, in *QueryDelegatorDelegationsRequest, opts ...grpc.CallOption) (*QueryDelegatorDelegationsResponse, error)
|
||||
// DelegatorUnbondingDelegations queries all unbonding delegations of a given
|
||||
// delegator address.
|
||||
//
|
||||
// When called from another module, this query might consume a high amount of
|
||||
// gas if the pagination field is incorrectly set.
|
||||
DelegatorUnbondingDelegations(ctx context.Context, in *QueryDelegatorUnbondingDelegationsRequest, opts ...grpc.CallOption) (*QueryDelegatorUnbondingDelegationsResponse, error)
|
||||
// Redelegations queries redelegations of given address.
|
||||
//
|
||||
// When called from another module, this query might consume a high amount of
|
||||
// gas if the pagination field is incorrectly set.
|
||||
Redelegations(ctx context.Context, in *QueryRedelegationsRequest, opts ...grpc.CallOption) (*QueryRedelegationsResponse, error)
|
||||
// DelegatorValidators queries all validators info for given delegator
|
||||
// address.
|
||||
//
|
||||
// When called from another module, this query might consume a high amount of
|
||||
// gas if the pagination field is incorrectly set.
|
||||
DelegatorValidators(ctx context.Context, in *QueryDelegatorValidatorsRequest, opts ...grpc.CallOption) (*QueryDelegatorValidatorsResponse, error)
|
||||
// DelegatorValidator queries validator info for given delegator validator
|
||||
// pair.
|
||||
@@ -195,12 +216,21 @@ func (c *queryClient) Params(ctx context.Context, in *QueryParamsRequest, opts .
|
||||
// for forward compatibility
|
||||
type QueryServer interface {
|
||||
// Validators queries all validators that match the given status.
|
||||
//
|
||||
// When called from another module, this query might consume a high amount of
|
||||
// gas if the pagination field is incorrectly set.
|
||||
Validators(context.Context, *QueryValidatorsRequest) (*QueryValidatorsResponse, error)
|
||||
// Validator queries validator info for given validator address.
|
||||
Validator(context.Context, *QueryValidatorRequest) (*QueryValidatorResponse, error)
|
||||
// ValidatorDelegations queries delegate info for given validator.
|
||||
//
|
||||
// When called from another module, this query might consume a high amount of
|
||||
// gas if the pagination field is incorrectly set.
|
||||
ValidatorDelegations(context.Context, *QueryValidatorDelegationsRequest) (*QueryValidatorDelegationsResponse, error)
|
||||
// ValidatorUnbondingDelegations queries unbonding delegations of a validator.
|
||||
//
|
||||
// When called from another module, this query might consume a high amount of
|
||||
// gas if the pagination field is incorrectly set.
|
||||
ValidatorUnbondingDelegations(context.Context, *QueryValidatorUnbondingDelegationsRequest) (*QueryValidatorUnbondingDelegationsResponse, error)
|
||||
// Delegation queries delegate info for given validator delegator pair.
|
||||
Delegation(context.Context, *QueryDelegationRequest) (*QueryDelegationResponse, error)
|
||||
@@ -208,14 +238,26 @@ type QueryServer interface {
|
||||
// pair.
|
||||
UnbondingDelegation(context.Context, *QueryUnbondingDelegationRequest) (*QueryUnbondingDelegationResponse, error)
|
||||
// DelegatorDelegations queries all delegations of a given delegator address.
|
||||
//
|
||||
// When called from another module, this query might consume a high amount of
|
||||
// gas if the pagination field is incorrectly set.
|
||||
DelegatorDelegations(context.Context, *QueryDelegatorDelegationsRequest) (*QueryDelegatorDelegationsResponse, error)
|
||||
// DelegatorUnbondingDelegations queries all unbonding delegations of a given
|
||||
// delegator address.
|
||||
//
|
||||
// When called from another module, this query might consume a high amount of
|
||||
// gas if the pagination field is incorrectly set.
|
||||
DelegatorUnbondingDelegations(context.Context, *QueryDelegatorUnbondingDelegationsRequest) (*QueryDelegatorUnbondingDelegationsResponse, error)
|
||||
// Redelegations queries redelegations of given address.
|
||||
//
|
||||
// When called from another module, this query might consume a high amount of
|
||||
// gas if the pagination field is incorrectly set.
|
||||
Redelegations(context.Context, *QueryRedelegationsRequest) (*QueryRedelegationsResponse, error)
|
||||
// DelegatorValidators queries all validators info for given delegator
|
||||
// address.
|
||||
//
|
||||
// When called from another module, this query might consume a high amount of
|
||||
// gas if the pagination field is incorrectly set.
|
||||
DelegatorValidators(context.Context, *QueryDelegatorValidatorsRequest) (*QueryDelegatorValidatorsResponse, error)
|
||||
// DelegatorValidator queries validator info for given delegator validator
|
||||
// pair.
|
||||
|
||||
Reference in New Issue
Block a user