x/bank: client denom metadata gRPC (#8317)
* deps: bump tendermint to v0.34.2 * x/bank: denom metadata gRPC * cli: add cmd and tests * gRPC test' * changelog * fix test * Apply suggestions from code review Co-authored-by: Robert Zaremba <robert@zaremba.ch> Co-authored-by: Aditya <adityasripal@gmail.com> * fix panic * use cmd.Context() * update tests * Update x/bank/types/errors.go Co-authored-by: colin axnér <25233464+colin-axner@users.noreply.github.com> * test fix Co-authored-by: Robert Zaremba <robert@zaremba.ch> Co-authored-by: Aditya <adityasripal@gmail.com> Co-authored-by: colin axnér <25233464+colin-axner@users.noreply.github.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
This commit is contained in:
parent
e8d47bb93b
commit
01eec66d28
|
@ -38,15 +38,16 @@ Ref: https://keepachangelog.com/en/1.0.0/
|
|||
|
||||
### Improvements
|
||||
|
||||
* (x/bank) [\#8302](https://github.com/cosmos/cosmos-sdk/issues/8302) Add gRPC and CLI queries for client denomination metadata.
|
||||
* (tendermint) [\#8316](https://github.com/cosmos/cosmos-sdk/pull/8316) Bump Tendermint version to [v0.34.2](https://github.com/tendermint/tendermint/releases/tag/v0.34.2)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* (x/bank) [\#8317](https://github.com/cosmos/cosmos-sdk/pull/8317) Fix panic when querying for a not found client denomination metadata.
|
||||
* (x/auth) [\#8287](https://github.com/cosmos/cosmos-sdk/pull/8287) Fix `tx sign --signature-only` to return correct sequence value in signature.
|
||||
* (x/ibc) [\#8341](https://github.com/cosmos/cosmos-sdk/pull/8341) Fix query latest consensus state.
|
||||
* (types/errors) [\#8355][https://github.com/cosmos/cosmos-sdk/pull/8355] Fix errorWrap `Is` method.
|
||||
|
||||
|
||||
## [v0.40.0](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.40.0) - 2021-01-08
|
||||
|
||||
v0.40.0, known as the Stargate release of the Cosmos SDK, is one of the largest releases
|
||||
|
|
|
@ -34,7 +34,7 @@ UX and remove the requirement for making any assumptions on the unit of denomina
|
|||
The `x/bank` module will be updated to store and index metadata by `denom`, specifically the "base" or
|
||||
smallest unit -- the unit the Cosmos SDK state-machine works with.
|
||||
|
||||
Metadata may also include a non-zero length list of denominations. Each entry containts the name of
|
||||
Metadata may also include a non-zero length list of denominations. Each entry contains the name of
|
||||
the denomination `denom`, the exponent to the base and a list of aliases. An entry is to be
|
||||
interpreted as `1 denom = 10^exponent base_denom` (e.g. `1 ETH = 10^18 wei` and `1 uatom = 10^0 uatom`).
|
||||
|
||||
|
@ -92,6 +92,7 @@ As an example, the ATOM's metadata can be defined as follows:
|
|||
```
|
||||
|
||||
Given the above metadata, a client may infer the following things:
|
||||
|
||||
- 4.3atom = 4.3 * (10^6) = 4,300,000uatom
|
||||
- The string "atom" can be used as a display name in a list of tokens.
|
||||
- The balance 4300000 can be displayed as 4,300,000uatom or 4,300matom or 4.3atom.
|
||||
|
|
|
@ -48,6 +48,10 @@
|
|||
- [QueryAllBalancesResponse](#cosmos.bank.v1beta1.QueryAllBalancesResponse)
|
||||
- [QueryBalanceRequest](#cosmos.bank.v1beta1.QueryBalanceRequest)
|
||||
- [QueryBalanceResponse](#cosmos.bank.v1beta1.QueryBalanceResponse)
|
||||
- [QueryDenomMetadataRequest](#cosmos.bank.v1beta1.QueryDenomMetadataRequest)
|
||||
- [QueryDenomMetadataResponse](#cosmos.bank.v1beta1.QueryDenomMetadataResponse)
|
||||
- [QueryDenomsMetadataRequest](#cosmos.bank.v1beta1.QueryDenomsMetadataRequest)
|
||||
- [QueryDenomsMetadataResponse](#cosmos.bank.v1beta1.QueryDenomsMetadataResponse)
|
||||
- [QueryParamsRequest](#cosmos.bank.v1beta1.QueryParamsRequest)
|
||||
- [QueryParamsResponse](#cosmos.bank.v1beta1.QueryParamsResponse)
|
||||
- [QuerySupplyOfRequest](#cosmos.bank.v1beta1.QuerySupplyOfRequest)
|
||||
|
@ -1274,6 +1278,69 @@ QueryBalanceResponse is the response type for the Query/Balance RPC method.
|
|||
|
||||
|
||||
|
||||
<a name="cosmos.bank.v1beta1.QueryDenomMetadataRequest"></a>
|
||||
|
||||
### QueryDenomMetadataRequest
|
||||
QueryDenomMetadataRequest is the request type for the Query/DenomMetadata RPC method.
|
||||
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| ----- | ---- | ----- | ----------- |
|
||||
| `denom` | [string](#string) | | denom is the coin denom to query the metadata for. |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a name="cosmos.bank.v1beta1.QueryDenomMetadataResponse"></a>
|
||||
|
||||
### QueryDenomMetadataResponse
|
||||
QueryDenomMetadataResponse is the response type for the Query/DenomMetadata RPC
|
||||
method.
|
||||
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| ----- | ---- | ----- | ----------- |
|
||||
| `metadata` | [Metadata](#cosmos.bank.v1beta1.Metadata) | | metadata describes and provides all the client information for the requested token. |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a name="cosmos.bank.v1beta1.QueryDenomsMetadataRequest"></a>
|
||||
|
||||
### QueryDenomsMetadataRequest
|
||||
QueryDenomsMetadataRequest is the request type for the Query/DenomsMetadata RPC method.
|
||||
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| ----- | ---- | ----- | ----------- |
|
||||
| `pagination` | [cosmos.base.query.v1beta1.PageRequest](#cosmos.base.query.v1beta1.PageRequest) | | pagination defines an optional pagination for the request. |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a name="cosmos.bank.v1beta1.QueryDenomsMetadataResponse"></a>
|
||||
|
||||
### QueryDenomsMetadataResponse
|
||||
QueryDenomsMetadataResponse is the response type for the Query/DenomsMetadata RPC
|
||||
method.
|
||||
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| ----- | ---- | ----- | ----------- |
|
||||
| `metadatas` | [Metadata](#cosmos.bank.v1beta1.Metadata) | repeated | metadata provides the client information for all the registered tokens. |
|
||||
| `pagination` | [cosmos.base.query.v1beta1.PageResponse](#cosmos.base.query.v1beta1.PageResponse) | | pagination defines the pagination in the response. |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a name="cosmos.bank.v1beta1.QueryParamsRequest"></a>
|
||||
|
||||
### QueryParamsRequest
|
||||
|
@ -1374,6 +1441,8 @@ Query defines the gRPC querier service.
|
|||
| `TotalSupply` | [QueryTotalSupplyRequest](#cosmos.bank.v1beta1.QueryTotalSupplyRequest) | [QueryTotalSupplyResponse](#cosmos.bank.v1beta1.QueryTotalSupplyResponse) | TotalSupply queries the total supply of all coins. | GET|/cosmos/bank/v1beta1/supply|
|
||||
| `SupplyOf` | [QuerySupplyOfRequest](#cosmos.bank.v1beta1.QuerySupplyOfRequest) | [QuerySupplyOfResponse](#cosmos.bank.v1beta1.QuerySupplyOfResponse) | SupplyOf queries the supply of a single coin. | GET|/cosmos/bank/v1beta1/supply/{denom}|
|
||||
| `Params` | [QueryParamsRequest](#cosmos.bank.v1beta1.QueryParamsRequest) | [QueryParamsResponse](#cosmos.bank.v1beta1.QueryParamsResponse) | Params queries the parameters of x/bank module. | GET|/cosmos/bank/v1beta1/params|
|
||||
| `DenomMetadata` | [QueryDenomMetadataRequest](#cosmos.bank.v1beta1.QueryDenomMetadataRequest) | [QueryDenomMetadataResponse](#cosmos.bank.v1beta1.QueryDenomMetadataResponse) | DenomsMetadata queries the client metadata of a given coin denomination. | GET|/cosmos/bank/v1beta1/denoms_metadata/{denom}|
|
||||
| `DenomsMetadata` | [QueryDenomsMetadataRequest](#cosmos.bank.v1beta1.QueryDenomsMetadataRequest) | [QueryDenomsMetadataResponse](#cosmos.bank.v1beta1.QueryDenomsMetadataResponse) | DenomsMetadata queries the client metadata for all registered coin denominations. | GET|/cosmos/bank/v1beta1/denoms_metadata|
|
||||
|
||||
<!-- end services -->
|
||||
|
||||
|
|
4
go.sum
4
go.sum
|
@ -544,7 +544,6 @@ github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoH
|
|||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
|
@ -562,7 +561,6 @@ github.com/tendermint/go-amino v0.16.0 h1:GyhmgQKvqF82e2oZeuMSp9JTN0N09emoSZlb2l
|
|||
github.com/tendermint/go-amino v0.16.0/go.mod h1:TQU0M1i/ImAo+tYpZi73AU3V/dKeCoMC9Sphe2ZwGME=
|
||||
github.com/tendermint/tendermint v0.34.0-rc4/go.mod h1:yotsojf2C1QBOw4dZrTcxbyxmPUrT4hNuOQWX9XUwB4=
|
||||
github.com/tendermint/tendermint v0.34.0-rc6/go.mod h1:ugzyZO5foutZImv0Iyx/gOFCX6mjJTgbLHTwi17VDVg=
|
||||
github.com/tendermint/tendermint v0.34.0 h1:eXCfMgoqVSzrjzOj6clI9GAejcHH0LvOlRjpCmMJksU=
|
||||
github.com/tendermint/tendermint v0.34.0/go.mod h1:Aj3PIipBFSNO21r+Lq3TtzQ+uKESxkbA3yo/INM4QwQ=
|
||||
github.com/tendermint/tendermint v0.34.2 h1:bB4xReGw4jalTDeNg0npYoONuZrD55F90LrWPF4m/PQ=
|
||||
github.com/tendermint/tendermint v0.34.2/go.mod h1:Aj3PIipBFSNO21r+Lq3TtzQ+uKESxkbA3yo/INM4QwQ=
|
||||
|
@ -618,7 +616,6 @@ golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899/go.mod h1:LzIPMQfyMNhhGPh
|
|||
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201117144127-c1f2f97bffc9 h1:phUcVbl53swtrUN8kQEXFhUxPlIlWyBfKmidCu7P95o=
|
||||
golang.org/x/crypto v0.0.0-20201117144127-c1f2f97bffc9/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad h1:DN0cp81fZ3njFcrLCytUHRSUkqBjfTo4Tx9RJTWs0EY=
|
||||
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
|
@ -797,7 +794,6 @@ google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfG
|
|||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201111145450-ac7456db90a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201119123407-9b1e624d6bc4 h1:Rt0FRalMgdSlXAVJvX4pr65KfqaxHXSLkSJRD9pw6g0=
|
||||
google.golang.org/genproto v0.0.0-20201119123407-9b1e624d6bc4/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20210114201628-6edceaf6022f h1:izedQ6yVIc5mZsRuXzmSreCOlzI0lCU1HpG8yEdMiKw=
|
||||
google.golang.org/genproto v0.0.0-20210114201628-6edceaf6022f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
|
|
|
@ -35,6 +35,16 @@ service Query {
|
|||
rpc Params(QueryParamsRequest) returns (QueryParamsResponse) {
|
||||
option (google.api.http).get = "/cosmos/bank/v1beta1/params";
|
||||
}
|
||||
|
||||
// DenomsMetadata queries the client metadata of a given coin denomination.
|
||||
rpc DenomMetadata(QueryDenomMetadataRequest) returns (QueryDenomMetadataResponse) {
|
||||
option (google.api.http).get = "/cosmos/bank/v1beta1/denoms_metadata/{denom}";
|
||||
}
|
||||
|
||||
// DenomsMetadata queries the client metadata for all registered coin denominations.
|
||||
rpc DenomsMetadata(QueryDenomsMetadataRequest) returns (QueryDenomsMetadataResponse) {
|
||||
option (google.api.http).get = "/cosmos/bank/v1beta1/denoms_metadata";
|
||||
}
|
||||
}
|
||||
|
||||
// QueryBalanceRequest is the request type for the Query/Balance RPC method.
|
||||
|
@ -109,3 +119,32 @@ message QueryParamsRequest {}
|
|||
message QueryParamsResponse {
|
||||
Params params = 1 [(gogoproto.nullable) = false];
|
||||
}
|
||||
|
||||
// QueryDenomsMetadataRequest is the request type for the Query/DenomsMetadata RPC method.
|
||||
message QueryDenomsMetadataRequest {
|
||||
// pagination defines an optional pagination for the request.
|
||||
cosmos.base.query.v1beta1.PageRequest pagination = 1;
|
||||
}
|
||||
|
||||
// QueryDenomsMetadataResponse is the response type for the Query/DenomsMetadata RPC
|
||||
// method.
|
||||
message QueryDenomsMetadataResponse {
|
||||
// metadata provides the client information for all the registered tokens.
|
||||
repeated Metadata metadatas = 1 [(gogoproto.nullable) = false];
|
||||
|
||||
// pagination defines the pagination in the response.
|
||||
cosmos.base.query.v1beta1.PageResponse pagination = 2;
|
||||
}
|
||||
|
||||
// QueryDenomMetadataRequest is the request type for the Query/DenomMetadata RPC method.
|
||||
message QueryDenomMetadataRequest {
|
||||
// denom is the coin denom to query the metadata for.
|
||||
string denom = 1;
|
||||
}
|
||||
|
||||
// QueryDenomMetadataResponse is the response type for the Query/DenomMetadata RPC
|
||||
// method.
|
||||
message QueryDenomMetadataResponse {
|
||||
// metadata describes and provides all the client information for the requested token.
|
||||
Metadata metadata = 1 [(gogoproto.nullable) = false];
|
||||
}
|
||||
|
|
|
@ -32,12 +32,57 @@ func (s *IntegrationTestSuite) SetupSuite() {
|
|||
s.T().Log("setting up integration test suite")
|
||||
|
||||
cfg := network.DefaultConfig()
|
||||
genesisState := cfg.GenesisState
|
||||
cfg.NumValidators = 1
|
||||
|
||||
var bankGenesis types.GenesisState
|
||||
s.Require().NoError(cfg.Codec.UnmarshalJSON(genesisState[types.ModuleName], &bankGenesis))
|
||||
|
||||
bankGenesis.DenomMetadata = []types.Metadata{
|
||||
{
|
||||
Description: "The native staking token of the Cosmos Hub.",
|
||||
DenomUnits: []*types.DenomUnit{
|
||||
{
|
||||
Denom: "uatom",
|
||||
Exponent: 0,
|
||||
Aliases: []string{"microatom"},
|
||||
},
|
||||
{
|
||||
Denom: "atom",
|
||||
Exponent: 6,
|
||||
Aliases: []string{"ATOM"},
|
||||
},
|
||||
},
|
||||
Base: "uatom",
|
||||
Display: "atom",
|
||||
},
|
||||
{
|
||||
Description: "Ethereum mainnet token",
|
||||
DenomUnits: []*types.DenomUnit{
|
||||
{
|
||||
Denom: "wei",
|
||||
Exponent: 0,
|
||||
},
|
||||
{
|
||||
Denom: "eth",
|
||||
Exponent: 6,
|
||||
Aliases: []string{"ETH"},
|
||||
},
|
||||
},
|
||||
Base: "wei",
|
||||
Display: "eth",
|
||||
},
|
||||
}
|
||||
|
||||
bankGenesisBz, err := cfg.Codec.MarshalJSON(&bankGenesis)
|
||||
s.Require().NoError(err)
|
||||
genesisState[types.ModuleName] = bankGenesisBz
|
||||
cfg.GenesisState = genesisState
|
||||
|
||||
s.cfg = cfg
|
||||
s.network = network.New(s.T(), cfg)
|
||||
|
||||
_, err := s.network.WaitForHeight(1)
|
||||
_, err = s.network.WaitForHeight(1)
|
||||
s.Require().NoError(err)
|
||||
}
|
||||
|
||||
|
@ -181,6 +226,127 @@ func (s *IntegrationTestSuite) TestGetCmdQueryTotalSupply() {
|
|||
}
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestGetCmdQueryDenomsMetadata() {
|
||||
val := s.network.Validators[0]
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
args []string
|
||||
expectErr bool
|
||||
respType proto.Message
|
||||
expected proto.Message
|
||||
}{
|
||||
{
|
||||
name: "all denoms client metadata",
|
||||
args: []string{
|
||||
fmt.Sprintf("--%s=1", flags.FlagHeight),
|
||||
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||
},
|
||||
respType: &types.QueryDenomsMetadataResponse{},
|
||||
expected: &types.QueryDenomsMetadataResponse{
|
||||
Metadatas: []types.Metadata{
|
||||
{
|
||||
Description: "The native staking token of the Cosmos Hub.",
|
||||
DenomUnits: []*types.DenomUnit{
|
||||
{
|
||||
Denom: "uatom",
|
||||
Exponent: 0,
|
||||
Aliases: []string{"microatom"},
|
||||
},
|
||||
{
|
||||
Denom: "atom",
|
||||
Exponent: 6,
|
||||
Aliases: []string{"ATOM"},
|
||||
},
|
||||
},
|
||||
Base: "uatom",
|
||||
Display: "atom",
|
||||
},
|
||||
{
|
||||
Description: "Ethereum mainnet token",
|
||||
DenomUnits: []*types.DenomUnit{
|
||||
{
|
||||
Denom: "wei",
|
||||
Exponent: 0,
|
||||
Aliases: []string{},
|
||||
},
|
||||
{
|
||||
Denom: "eth",
|
||||
Exponent: 6,
|
||||
Aliases: []string{"ETH"},
|
||||
},
|
||||
},
|
||||
Base: "wei",
|
||||
Display: "eth",
|
||||
},
|
||||
},
|
||||
Pagination: &query.PageResponse{Total: 2},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "client metadata of a specific denomination",
|
||||
args: []string{
|
||||
fmt.Sprintf("--%s=1", flags.FlagHeight),
|
||||
fmt.Sprintf("--%s=%s", cli.FlagDenom, "uatom"),
|
||||
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||
},
|
||||
respType: &types.QueryDenomMetadataResponse{},
|
||||
expected: &types.QueryDenomMetadataResponse{
|
||||
Metadata: types.Metadata{
|
||||
Description: "The native staking token of the Cosmos Hub.",
|
||||
DenomUnits: []*types.DenomUnit{
|
||||
{
|
||||
Denom: "uatom",
|
||||
Exponent: 0,
|
||||
Aliases: []string{"microatom"},
|
||||
},
|
||||
{
|
||||
Denom: "atom",
|
||||
Exponent: 6,
|
||||
Aliases: []string{"ATOM"},
|
||||
},
|
||||
},
|
||||
Base: "uatom",
|
||||
Display: "atom",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "client metadata of a bogus denom",
|
||||
args: []string{
|
||||
fmt.Sprintf("--%s=1", flags.FlagHeight),
|
||||
fmt.Sprintf("--%s=foobar", cli.FlagDenom),
|
||||
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||
},
|
||||
expectErr: true,
|
||||
respType: &types.QueryDenomMetadataResponse{},
|
||||
expected: &types.QueryDenomMetadataResponse{
|
||||
Metadata: types.Metadata{
|
||||
DenomUnits: []*types.DenomUnit{},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
tc := tc
|
||||
|
||||
s.Run(tc.name, func() {
|
||||
cmd := cli.GetCmdDenomsMetadata()
|
||||
clientCtx := val.ClientCtx
|
||||
|
||||
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
|
||||
if tc.expectErr {
|
||||
s.Require().Error(err)
|
||||
} else {
|
||||
s.Require().NoError(err)
|
||||
s.Require().NoError(clientCtx.JSONMarshaler.UnmarshalJSON(out.Bytes(), tc.respType))
|
||||
s.Require().Equal(tc.expected, tc.respType)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestNewSendTxCmdGenOnly() {
|
||||
val := s.network.Validators[0]
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package cli
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
|
@ -33,6 +32,7 @@ func GetQueryCmd() *cobra.Command {
|
|||
cmd.AddCommand(
|
||||
GetBalancesCmd(),
|
||||
GetCmdQueryTotalSupply(),
|
||||
GetCmdDenomsMetadata(),
|
||||
)
|
||||
|
||||
return cmd
|
||||
|
@ -78,7 +78,7 @@ Example:
|
|||
if denom == "" {
|
||||
params := types.NewQueryAllBalancesRequest(addr, pageReq)
|
||||
|
||||
res, err := queryClient.AllBalances(context.Background(), params)
|
||||
res, err := queryClient.AllBalances(cmd.Context(), params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -86,7 +86,7 @@ Example:
|
|||
}
|
||||
|
||||
params := types.NewQueryBalanceRequest(addr, denom)
|
||||
res, err := queryClient.Balance(context.Background(), params)
|
||||
res, err := queryClient.Balance(cmd.Context(), params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -102,6 +102,60 @@ Example:
|
|||
return cmd
|
||||
}
|
||||
|
||||
// GetCmdDenomsMetadata defines the cobra command to query client denomination metadata.
|
||||
func GetCmdDenomsMetadata() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "denom-metadata",
|
||||
Short: "Query the client metadata for coin denominations",
|
||||
Long: strings.TrimSpace(
|
||||
fmt.Sprintf(`Query the client metadata for all the registered coin denominations
|
||||
|
||||
Example:
|
||||
To query for the client metadata of all coin denominations use:
|
||||
$ %s query %s denom-metadata
|
||||
|
||||
To query for the client metadata of a specific coin denomination use:
|
||||
$ %s query %s denom-metadata --denom=[denom]
|
||||
`,
|
||||
version.AppName, types.ModuleName, version.AppName, types.ModuleName,
|
||||
),
|
||||
),
|
||||
RunE: func(cmd *cobra.Command, _ []string) error {
|
||||
clientCtx, err := client.GetClientQueryContext(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
denom, err := cmd.Flags().GetString(FlagDenom)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
queryClient := types.NewQueryClient(clientCtx)
|
||||
|
||||
if denom == "" {
|
||||
res, err := queryClient.DenomsMetadata(cmd.Context(), &types.QueryDenomsMetadataRequest{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return clientCtx.PrintProto(res)
|
||||
}
|
||||
|
||||
res, err := queryClient.DenomMetadata(cmd.Context(), &types.QueryDenomMetadataRequest{Denom: denom})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return clientCtx.PrintProto(res)
|
||||
},
|
||||
}
|
||||
|
||||
cmd.Flags().String(FlagDenom, "", "The specific denomination to query client metadata for")
|
||||
flags.AddQueryFlagsToCmd(cmd)
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func GetCmdQueryTotalSupply() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "total",
|
||||
|
@ -131,7 +185,7 @@ To query for the total supply of a specific coin denomination use:
|
|||
queryClient := types.NewQueryClient(clientCtx)
|
||||
|
||||
if denom == "" {
|
||||
res, err := queryClient.TotalSupply(context.Background(), &types.QueryTotalSupplyRequest{})
|
||||
res, err := queryClient.TotalSupply(cmd.Context(), &types.QueryTotalSupplyRequest{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -139,7 +193,7 @@ To query for the total supply of a specific coin denomination use:
|
|||
return clientCtx.PrintProto(res)
|
||||
}
|
||||
|
||||
res, err := queryClient.SupplyOf(context.Background(), &types.QuerySupplyOfRequest{Denom: denom})
|
||||
res, err := queryClient.SupplyOf(cmd.Context(), &types.QuerySupplyOfRequest{Denom: denom})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -98,6 +98,109 @@ func (s *IntegrationTestSuite) TestTotalSupplyGRPCHandler() {
|
|||
}
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestDenomMetadataGRPCHandler() {
|
||||
val := s.network.Validators[0]
|
||||
baseURL := val.APIAddress
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
url string
|
||||
headers map[string]string
|
||||
expErr bool
|
||||
respType proto.Message
|
||||
expected proto.Message
|
||||
}{
|
||||
{
|
||||
"test GRPC client metadata",
|
||||
fmt.Sprintf("%s/cosmos/bank/v1beta1/denoms_metadata", baseURL),
|
||||
map[string]string{
|
||||
grpctypes.GRPCBlockHeightHeader: "1",
|
||||
},
|
||||
false,
|
||||
&types.QueryDenomsMetadataResponse{},
|
||||
&types.QueryDenomsMetadataResponse{
|
||||
Metadatas: []types.Metadata{
|
||||
{
|
||||
Description: "The native staking token of the Cosmos Hub.",
|
||||
DenomUnits: []*types.DenomUnit{
|
||||
{
|
||||
Denom: "uatom",
|
||||
Exponent: 0,
|
||||
Aliases: []string{"microatom"},
|
||||
},
|
||||
{
|
||||
Denom: "atom",
|
||||
Exponent: 6,
|
||||
Aliases: []string{"ATOM"},
|
||||
},
|
||||
},
|
||||
Base: "uatom",
|
||||
Display: "atom",
|
||||
},
|
||||
},
|
||||
Pagination: &query.PageResponse{Total: 1},
|
||||
},
|
||||
},
|
||||
{
|
||||
"GRPC client metadata of a specific denom",
|
||||
fmt.Sprintf("%s/cosmos/bank/v1beta1/denoms_metadata/uatom", baseURL),
|
||||
map[string]string{
|
||||
grpctypes.GRPCBlockHeightHeader: "1",
|
||||
},
|
||||
false,
|
||||
&types.QueryDenomMetadataResponse{},
|
||||
&types.QueryDenomMetadataResponse{
|
||||
Metadata: types.Metadata{
|
||||
Description: "The native staking token of the Cosmos Hub.",
|
||||
DenomUnits: []*types.DenomUnit{
|
||||
{
|
||||
Denom: "uatom",
|
||||
Exponent: 0,
|
||||
Aliases: []string{"microatom"},
|
||||
},
|
||||
{
|
||||
Denom: "atom",
|
||||
Exponent: 6,
|
||||
Aliases: []string{"ATOM"},
|
||||
},
|
||||
},
|
||||
Base: "uatom",
|
||||
Display: "atom",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
"GRPC client metadata of a bogus denom",
|
||||
fmt.Sprintf("%s/cosmos/bank/v1beta1/denoms_metadata/foobar", baseURL),
|
||||
map[string]string{
|
||||
grpctypes.GRPCBlockHeightHeader: "1",
|
||||
},
|
||||
true,
|
||||
&types.QueryDenomMetadataResponse{},
|
||||
&types.QueryDenomMetadataResponse{
|
||||
Metadata: types.Metadata{
|
||||
DenomUnits: []*types.DenomUnit{},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
tc := tc
|
||||
s.Run(tc.name, func() {
|
||||
resp, err := testutil.GetRequestWithHeaders(tc.url, tc.headers)
|
||||
s.Require().NoError(err)
|
||||
|
||||
if tc.expErr {
|
||||
s.Require().Error(val.ClientCtx.JSONMarshaler.UnmarshalJSON(resp, tc.respType))
|
||||
} else {
|
||||
s.Require().NoError(val.ClientCtx.JSONMarshaler.UnmarshalJSON(resp, tc.respType))
|
||||
s.Require().Equal(tc.expected.String(), tc.respType.String())
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestBalancesGRPCHandler() {
|
||||
val := s.network.Validators[0]
|
||||
baseURL := val.APIAddress
|
||||
|
|
|
@ -11,6 +11,7 @@ import (
|
|||
"github.com/cosmos/cosmos-sdk/testutil/network"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/rest"
|
||||
"github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||
)
|
||||
|
||||
type IntegrationTestSuite struct {
|
||||
|
@ -24,12 +25,41 @@ func (s *IntegrationTestSuite) SetupSuite() {
|
|||
s.T().Log("setting up integration test suite")
|
||||
|
||||
cfg := network.DefaultConfig()
|
||||
genesisState := cfg.GenesisState
|
||||
cfg.NumValidators = 1
|
||||
|
||||
var bankGenesis types.GenesisState
|
||||
s.Require().NoError(cfg.Codec.UnmarshalJSON(genesisState[types.ModuleName], &bankGenesis))
|
||||
|
||||
bankGenesis.DenomMetadata = []types.Metadata{
|
||||
{
|
||||
Description: "The native staking token of the Cosmos Hub.",
|
||||
DenomUnits: []*types.DenomUnit{
|
||||
{
|
||||
Denom: "uatom",
|
||||
Exponent: 0,
|
||||
Aliases: []string{"microatom"},
|
||||
},
|
||||
{
|
||||
Denom: "atom",
|
||||
Exponent: 6,
|
||||
Aliases: []string{"ATOM"},
|
||||
},
|
||||
},
|
||||
Base: "uatom",
|
||||
Display: "atom",
|
||||
},
|
||||
}
|
||||
|
||||
bankGenesisBz, err := cfg.Codec.MarshalJSON(&bankGenesis)
|
||||
s.Require().NoError(err)
|
||||
genesisState[types.ModuleName] = bankGenesisBz
|
||||
cfg.GenesisState = genesisState
|
||||
|
||||
s.cfg = cfg
|
||||
s.network = network.New(s.T(), cfg)
|
||||
|
||||
_, err := s.network.WaitForHeight(2)
|
||||
_, err = s.network.WaitForHeight(2)
|
||||
s.Require().NoError(err)
|
||||
}
|
||||
|
||||
|
|
|
@ -44,13 +44,13 @@ func (suite *IntegrationTestSuite) getTestBalances() []types.Balance {
|
|||
}
|
||||
|
||||
func (suite *IntegrationTestSuite) TestInitGenesis() {
|
||||
require := suite.Require()
|
||||
m := types.Metadata{Description: sdk.DefaultBondDenom, Base: sdk.DefaultBondDenom, Display: sdk.DefaultBondDenom}
|
||||
g := types.DefaultGenesisState()
|
||||
g.DenomMetadata = []types.Metadata{m}
|
||||
bk := suite.app.BankKeeper
|
||||
bk.InitGenesis(suite.ctx, g)
|
||||
|
||||
m2 := bk.GetDenomMetaData(suite.ctx, m.Base)
|
||||
require.Equal(m, m2)
|
||||
m2, found := bk.GetDenomMetaData(suite.ctx, m.Base)
|
||||
suite.Require().True(found)
|
||||
suite.Require().Equal(m, m2)
|
||||
}
|
||||
|
|
|
@ -61,7 +61,7 @@ func (k BaseKeeper) AllBalances(ctx context.Context, req *types.QueryAllBalances
|
|||
balancesStore := prefix.NewStore(store, types.BalancesPrefix)
|
||||
accountStore := prefix.NewStore(balancesStore, addr.Bytes())
|
||||
|
||||
pageRes, err := query.Paginate(accountStore, req.Pagination, func(key []byte, value []byte) error {
|
||||
pageRes, err := query.Paginate(accountStore, req.Pagination, func(_, value []byte) error {
|
||||
var result sdk.Coin
|
||||
err := k.cdc.UnmarshalBinaryBare(value, &result)
|
||||
if err != nil {
|
||||
|
@ -113,3 +113,53 @@ func (k BaseKeeper) Params(ctx context.Context, req *types.QueryParamsRequest) (
|
|||
|
||||
return &types.QueryParamsResponse{Params: params}, nil
|
||||
}
|
||||
|
||||
// DenomsMetadata implements Query/DenomsMetadata gRPC method.
|
||||
func (k BaseKeeper) DenomsMetadata(c context.Context, req *types.QueryDenomsMetadataRequest) (*types.QueryDenomsMetadataResponse, error) {
|
||||
if req == nil {
|
||||
return nil, status.Errorf(codes.InvalidArgument, "empty request")
|
||||
}
|
||||
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
store := prefix.NewStore(ctx.KVStore(k.storeKey), types.DenomMetadataPrefix)
|
||||
|
||||
metadatas := []types.Metadata{}
|
||||
pageRes, err := query.Paginate(store, req.Pagination, func(_, value []byte) error {
|
||||
var metadata types.Metadata
|
||||
k.cdc.MustUnmarshalBinaryBare(value, &metadata)
|
||||
|
||||
metadatas = append(metadatas, metadata)
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
|
||||
return &types.QueryDenomsMetadataResponse{
|
||||
Metadatas: metadatas,
|
||||
Pagination: pageRes,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// DenomMetadata implements Query/DenomMetadata gRPC method.
|
||||
func (k BaseKeeper) DenomMetadata(c context.Context, req *types.QueryDenomMetadataRequest) (*types.QueryDenomMetadataResponse, error) {
|
||||
if req == nil {
|
||||
return nil, status.Errorf(codes.InvalidArgument, "empty request")
|
||||
}
|
||||
|
||||
if req.Denom == "" {
|
||||
return nil, status.Error(codes.InvalidArgument, "invalid denom")
|
||||
}
|
||||
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
|
||||
metadata, found := k.GetDenomMetaData(ctx, req.Denom)
|
||||
if !found {
|
||||
return nil, status.Errorf(codes.NotFound, "client metadata for denom %s", req.Denom)
|
||||
}
|
||||
|
||||
return &types.QueryDenomMetadataResponse{
|
||||
Metadata: metadata,
|
||||
}, nil
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ package keeper_test
|
|||
|
||||
import (
|
||||
gocontext "context"
|
||||
"fmt"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/testutil/testdata"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
|
@ -119,3 +120,182 @@ func (suite *IntegrationTestSuite) TestQueryParams() {
|
|||
suite.Require().NotNil(res)
|
||||
suite.Require().Equal(suite.app.BankKeeper.GetParams(suite.ctx), res.GetParams())
|
||||
}
|
||||
|
||||
func (suite *IntegrationTestSuite) QueryDenomsMetadataRequest() {
|
||||
var (
|
||||
req *types.QueryDenomsMetadataRequest
|
||||
expMetadata = []types.Metadata{}
|
||||
)
|
||||
|
||||
testCases := []struct {
|
||||
msg string
|
||||
malleate func()
|
||||
expPass bool
|
||||
}{
|
||||
{
|
||||
"empty pagination",
|
||||
func() {
|
||||
req = &types.QueryDenomsMetadataRequest{}
|
||||
},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"success, no results",
|
||||
func() {
|
||||
req = &types.QueryDenomsMetadataRequest{
|
||||
Pagination: &query.PageRequest{
|
||||
Limit: 3,
|
||||
CountTotal: true,
|
||||
},
|
||||
}
|
||||
},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"success",
|
||||
func() {
|
||||
metadataAtom := types.Metadata{
|
||||
Description: "The native staking token of the Cosmos Hub.",
|
||||
DenomUnits: []*types.DenomUnit{
|
||||
{
|
||||
Denom: "uatom",
|
||||
Exponent: 0,
|
||||
Aliases: []string{"microatom"},
|
||||
},
|
||||
{
|
||||
Denom: "atom",
|
||||
Exponent: 6,
|
||||
Aliases: []string{"ATOM"},
|
||||
},
|
||||
},
|
||||
Base: "uatom",
|
||||
Display: "atom",
|
||||
}
|
||||
|
||||
metadataEth := types.Metadata{
|
||||
Description: "Ethereum native token",
|
||||
DenomUnits: []*types.DenomUnit{
|
||||
{
|
||||
Denom: "wei",
|
||||
Exponent: 0,
|
||||
},
|
||||
{
|
||||
Denom: "eth",
|
||||
Exponent: 18,
|
||||
Aliases: []string{"ETH", "ether"},
|
||||
},
|
||||
},
|
||||
Base: "wei",
|
||||
Display: "eth",
|
||||
}
|
||||
|
||||
suite.app.BankKeeper.SetDenomMetaData(suite.ctx, metadataAtom)
|
||||
suite.app.BankKeeper.SetDenomMetaData(suite.ctx, metadataEth)
|
||||
expMetadata = []types.Metadata{metadataAtom, metadataEth}
|
||||
req = &types.QueryDenomsMetadataRequest{
|
||||
Pagination: &query.PageRequest{
|
||||
Limit: 7,
|
||||
CountTotal: true,
|
||||
},
|
||||
}
|
||||
},
|
||||
true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
|
||||
suite.SetupTest() // reset
|
||||
|
||||
tc.malleate()
|
||||
ctx := sdk.WrapSDKContext(suite.ctx)
|
||||
|
||||
res, err := suite.queryClient.DenomsMetadata(ctx, req)
|
||||
|
||||
if tc.expPass {
|
||||
suite.Require().NoError(err)
|
||||
suite.Require().NotNil(res)
|
||||
suite.Require().Equal(expMetadata, res.Metadatas)
|
||||
} else {
|
||||
suite.Require().Error(err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *IntegrationTestSuite) QueryDenomMetadataRequest() {
|
||||
var (
|
||||
req *types.QueryDenomMetadataRequest
|
||||
expMetadata = types.Metadata{}
|
||||
)
|
||||
|
||||
testCases := []struct {
|
||||
msg string
|
||||
malleate func()
|
||||
expPass bool
|
||||
}{
|
||||
{
|
||||
"empty denom",
|
||||
func() {
|
||||
req = &types.QueryDenomMetadataRequest{}
|
||||
},
|
||||
false,
|
||||
},
|
||||
{
|
||||
"not found denom",
|
||||
func() {
|
||||
req = &types.QueryDenomMetadataRequest{
|
||||
Denom: "foo",
|
||||
}
|
||||
},
|
||||
false,
|
||||
},
|
||||
{
|
||||
"success",
|
||||
func() {
|
||||
expMetadata := types.Metadata{
|
||||
Description: "The native staking token of the Cosmos Hub.",
|
||||
DenomUnits: []*types.DenomUnit{
|
||||
{
|
||||
Denom: "uatom",
|
||||
Exponent: 0,
|
||||
Aliases: []string{"microatom"},
|
||||
},
|
||||
{
|
||||
Denom: "atom",
|
||||
Exponent: 6,
|
||||
Aliases: []string{"ATOM"},
|
||||
},
|
||||
},
|
||||
Base: "uatom",
|
||||
Display: "atom",
|
||||
}
|
||||
|
||||
suite.app.BankKeeper.SetDenomMetaData(suite.ctx, expMetadata)
|
||||
req = &types.QueryDenomMetadataRequest{
|
||||
Denom: expMetadata.Base,
|
||||
}
|
||||
},
|
||||
true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
|
||||
suite.SetupTest() // reset
|
||||
|
||||
tc.malleate()
|
||||
ctx := sdk.WrapSDKContext(suite.ctx)
|
||||
|
||||
res, err := suite.queryClient.DenomMetadata(ctx, req)
|
||||
|
||||
if tc.expPass {
|
||||
suite.Require().NoError(err)
|
||||
suite.Require().NotNil(res)
|
||||
suite.Require().Equal(expMetadata, res.Metadata)
|
||||
} else {
|
||||
suite.Require().Error(err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ type Keeper interface {
|
|||
GetSupply(ctx sdk.Context) exported.SupplyI
|
||||
SetSupply(ctx sdk.Context, supply exported.SupplyI)
|
||||
|
||||
GetDenomMetaData(ctx sdk.Context, denom string) types.Metadata
|
||||
GetDenomMetaData(ctx sdk.Context, denom string) (types.Metadata, bool)
|
||||
SetDenomMetaData(ctx sdk.Context, denomMetaData types.Metadata)
|
||||
IterateAllDenomMetaData(ctx sdk.Context, cb func(types.Metadata) bool)
|
||||
|
||||
|
@ -180,15 +180,19 @@ func (k BaseKeeper) SetSupply(ctx sdk.Context, supply exported.SupplyI) {
|
|||
}
|
||||
|
||||
// GetDenomMetaData retrieves the denomination metadata
|
||||
func (k BaseKeeper) GetDenomMetaData(ctx sdk.Context, denom string) types.Metadata {
|
||||
func (k BaseKeeper) GetDenomMetaData(ctx sdk.Context, denom string) (types.Metadata, bool) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
store = prefix.NewStore(store, types.DenomMetadataKey(denom))
|
||||
|
||||
bz := store.Get([]byte(denom))
|
||||
if bz == nil {
|
||||
return types.Metadata{}, false
|
||||
}
|
||||
|
||||
var metadata types.Metadata
|
||||
k.cdc.MustUnmarshalBinaryBare(bz, &metadata)
|
||||
|
||||
return metadata
|
||||
return metadata, true
|
||||
}
|
||||
|
||||
// GetAllDenomMetaData retrieves all denominations metadata
|
||||
|
|
|
@ -981,8 +981,8 @@ func (suite *IntegrationTestSuite) TestSetDenomMetaData() {
|
|||
app.BankKeeper.SetDenomMetaData(ctx, metadata[i])
|
||||
}
|
||||
|
||||
actualMetadata := app.BankKeeper.GetDenomMetaData(ctx, metadata[1].Base)
|
||||
|
||||
actualMetadata, found := app.BankKeeper.GetDenomMetaData(ctx, metadata[1].Base)
|
||||
suite.Require().True(found)
|
||||
suite.Require().Equal(metadata[1].GetBase(), actualMetadata.GetBase())
|
||||
suite.Require().Equal(metadata[1].GetDisplay(), actualMetadata.GetDisplay())
|
||||
suite.Require().Equal(metadata[1].GetDescription(), actualMetadata.GetDescription())
|
||||
|
|
|
@ -6,8 +6,9 @@ import (
|
|||
|
||||
// x/bank module sentinel errors
|
||||
var (
|
||||
ErrNoInputs = sdkerrors.Register(ModuleName, 2, "no inputs to send transaction")
|
||||
ErrNoOutputs = sdkerrors.Register(ModuleName, 3, "no outputs to send transaction")
|
||||
ErrInputOutputMismatch = sdkerrors.Register(ModuleName, 4, "sum inputs != sum outputs")
|
||||
ErrSendDisabled = sdkerrors.Register(ModuleName, 5, "send transactions are disabled")
|
||||
ErrNoInputs = sdkerrors.Register(ModuleName, 2, "no inputs to send transaction")
|
||||
ErrNoOutputs = sdkerrors.Register(ModuleName, 3, "no outputs to send transaction")
|
||||
ErrInputOutputMismatch = sdkerrors.Register(ModuleName, 4, "sum inputs != sum outputs")
|
||||
ErrSendDisabled = sdkerrors.Register(ModuleName, 5, "send transactions are disabled")
|
||||
ErrDenomMetadataNotFound = sdkerrors.Register(ModuleName, 6, "client denom metadata not found")
|
||||
)
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -269,6 +269,96 @@ func local_request_Query_Params_0(ctx context.Context, marshaler runtime.Marshal
|
|||
|
||||
}
|
||||
|
||||
func request_Query_DenomMetadata_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq QueryDenomMetadataRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
var (
|
||||
val string
|
||||
ok bool
|
||||
err error
|
||||
_ = err
|
||||
)
|
||||
|
||||
val, ok = pathParams["denom"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "denom")
|
||||
}
|
||||
|
||||
protoReq.Denom, err = runtime.String(val)
|
||||
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "denom", err)
|
||||
}
|
||||
|
||||
msg, err := client.DenomMetadata(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func local_request_Query_DenomMetadata_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq QueryDenomMetadataRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
var (
|
||||
val string
|
||||
ok bool
|
||||
err error
|
||||
_ = err
|
||||
)
|
||||
|
||||
val, ok = pathParams["denom"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "denom")
|
||||
}
|
||||
|
||||
protoReq.Denom, err = runtime.String(val)
|
||||
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "denom", err)
|
||||
}
|
||||
|
||||
msg, err := server.DenomMetadata(ctx, &protoReq)
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
var (
|
||||
filter_Query_DenomsMetadata_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)}
|
||||
)
|
||||
|
||||
func request_Query_DenomsMetadata_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq QueryDenomsMetadataRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
if err := req.ParseForm(); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_DenomsMetadata_0); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
msg, err := client.DenomsMetadata(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func local_request_Query_DenomsMetadata_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq QueryDenomsMetadataRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
if err := req.ParseForm(); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_DenomsMetadata_0); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
msg, err := server.DenomsMetadata(ctx, &protoReq)
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
// RegisterQueryHandlerServer registers the http handlers for service Query to "mux".
|
||||
// UnaryRPC :call QueryServer directly.
|
||||
// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.
|
||||
|
@ -375,6 +465,46 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv
|
|||
|
||||
})
|
||||
|
||||
mux.Handle("GET", pattern_Query_DenomMetadata_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := local_request_Query_DenomMetadata_0(rctx, inboundMarshaler, server, req, pathParams)
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_Query_DenomMetadata_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("GET", pattern_Query_DenomsMetadata_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := local_request_Query_DenomsMetadata_0(rctx, inboundMarshaler, server, req, pathParams)
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_Query_DenomsMetadata_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -516,6 +646,46 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie
|
|||
|
||||
})
|
||||
|
||||
mux.Handle("GET", pattern_Query_DenomMetadata_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateContext(ctx, mux, req)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := request_Query_DenomMetadata_0(rctx, inboundMarshaler, client, req, pathParams)
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_Query_DenomMetadata_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("GET", pattern_Query_DenomsMetadata_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateContext(ctx, mux, req)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := request_Query_DenomsMetadata_0(rctx, inboundMarshaler, client, req, pathParams)
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_Query_DenomsMetadata_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -529,6 +699,10 @@ var (
|
|||
pattern_Query_SupplyOf_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"cosmos", "bank", "v1beta1", "supply", "denom"}, "", runtime.AssumeColonVerbOpt(true)))
|
||||
|
||||
pattern_Query_Params_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"cosmos", "bank", "v1beta1", "params"}, "", runtime.AssumeColonVerbOpt(true)))
|
||||
|
||||
pattern_Query_DenomMetadata_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"cosmos", "bank", "v1beta1", "denoms_metadata", "denom"}, "", runtime.AssumeColonVerbOpt(true)))
|
||||
|
||||
pattern_Query_DenomsMetadata_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"cosmos", "bank", "v1beta1", "denoms_metadata"}, "", runtime.AssumeColonVerbOpt(true)))
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -541,4 +715,8 @@ var (
|
|||
forward_Query_SupplyOf_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_Query_Params_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_Query_DenomMetadata_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_Query_DenomsMetadata_0 = runtime.ForwardResponseMessage
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue