bank: additional client metadata validation (#8479)
* bank: additional client metadata validation * changelog and comment * fix tab
This commit is contained in:
parent
d6e4a2e9bc
commit
1d75e0e984
@ -42,6 +42,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
|
||||
|
||||
### Improvements
|
||||
|
||||
* (x/bank) [\#8479](https://github.com/cosmos/cosmos-sdk/pull/8479) Adittional client denom metadata validation for `base` and `display` denoms.
|
||||
* (x/ibc) [\#8404](https://github.com/cosmos/cosmos-sdk/pull/8404) Reorder IBC `ChanOpenAck` and `ChanOpenConfirm` handler execution to perform core handler first, followed by application callbacks.
|
||||
* [\#8396](https://github.com/cosmos/cosmos-sdk/pull/8396) Add support for ARM platform
|
||||
|
||||
|
||||
@ -1,13 +1,19 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
// Validate performs a basic validation of the coin metadata fields
|
||||
// Validate performs a basic validation of the coin metadata fields. It checks:
|
||||
// - Base and Display denominations are valid coin denominations
|
||||
// - Base and Display denominations are present in the DenomUnit slice
|
||||
// - Base denomination has exponent 0
|
||||
// - Denomination units are sorted in ascending order
|
||||
// - Denomination units not duplicated
|
||||
func (m Metadata) Validate() error {
|
||||
if err := sdk.ValidateDenom(m.Base); err != nil {
|
||||
return fmt.Errorf("invalid metadata base denom: %w", err)
|
||||
@ -17,12 +23,37 @@ func (m Metadata) Validate() error {
|
||||
return fmt.Errorf("invalid metadata display denom: %w", err)
|
||||
}
|
||||
|
||||
var (
|
||||
hasDisplay bool
|
||||
currentExponent uint32 // check that the exponents are increasing
|
||||
)
|
||||
|
||||
seenUnits := make(map[string]bool)
|
||||
for _, denomUnit := range m.DenomUnits {
|
||||
|
||||
for i, denomUnit := range m.DenomUnits {
|
||||
// The first denomination unit MUST be the base
|
||||
if i == 0 {
|
||||
// validate denomination and exponent
|
||||
if denomUnit.Denom != m.Base {
|
||||
return fmt.Errorf("metadata's first denomination unit must be the one with base denom '%s'", m.Base)
|
||||
}
|
||||
if denomUnit.Exponent != 0 {
|
||||
return fmt.Errorf("the exponent for base denomination unit %s must be 0", m.Base)
|
||||
}
|
||||
} else if currentExponent >= denomUnit.Exponent {
|
||||
return errors.New("denom units should be sorted asc by exponent")
|
||||
}
|
||||
|
||||
currentExponent = denomUnit.Exponent
|
||||
|
||||
if seenUnits[denomUnit.Denom] {
|
||||
return fmt.Errorf("duplicate denomination unit %s", denomUnit.Denom)
|
||||
}
|
||||
|
||||
if denomUnit.Denom == m.Display {
|
||||
hasDisplay = true
|
||||
}
|
||||
|
||||
if err := denomUnit.Validate(); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -30,6 +61,10 @@ func (m Metadata) Validate() error {
|
||||
seenUnits[denomUnit.Denom] = true
|
||||
}
|
||||
|
||||
if !hasDisplay {
|
||||
return fmt.Errorf("metadata must contain a denomination unit with display denom '%s'", m.Display)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@ -51,7 +51,7 @@ func TestMetadataValidate(t *testing.T) {
|
||||
Description: "The native staking token of the Cosmos Hub.",
|
||||
DenomUnits: []*types.DenomUnit{
|
||||
{"uatom", uint32(0), []string{"microatom"}},
|
||||
{"uatom", uint32(0), []string{"microatom"}},
|
||||
{"uatom", uint32(1), []string{"microatom"}},
|
||||
},
|
||||
Base: "uatom",
|
||||
Display: "atom",
|
||||
@ -94,6 +94,59 @@ func TestMetadataValidate(t *testing.T) {
|
||||
},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"no base denom unit",
|
||||
types.Metadata{
|
||||
Description: "The native staking token of the Cosmos Hub.",
|
||||
DenomUnits: []*types.DenomUnit{
|
||||
{"matom", uint32(3), []string{"milliatom"}},
|
||||
{"atom", uint32(6), nil},
|
||||
},
|
||||
Base: "uatom",
|
||||
Display: "atom",
|
||||
},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"base denom exponent not zero",
|
||||
types.Metadata{
|
||||
Description: "The native staking token of the Cosmos Hub.",
|
||||
DenomUnits: []*types.DenomUnit{
|
||||
{"uatom", uint32(1), []string{"microatom"}},
|
||||
{"matom", uint32(3), []string{"milliatom"}},
|
||||
{"atom", uint32(6), nil},
|
||||
},
|
||||
Base: "uatom",
|
||||
Display: "atom",
|
||||
},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"no display denom unit",
|
||||
types.Metadata{
|
||||
Description: "The native staking token of the Cosmos Hub.",
|
||||
DenomUnits: []*types.DenomUnit{
|
||||
{"uatom", uint32(0), []string{"microatom"}},
|
||||
},
|
||||
Base: "uatom",
|
||||
Display: "atom",
|
||||
},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"denom units not sorted",
|
||||
types.Metadata{
|
||||
Description: "The native staking token of the Cosmos Hub.",
|
||||
DenomUnits: []*types.DenomUnit{
|
||||
{"uatom", uint32(0), []string{"microatom"}},
|
||||
{"atom", uint32(6), nil},
|
||||
{"matom", uint32(3), []string{"milliatom"}},
|
||||
},
|
||||
Base: "uatom",
|
||||
Display: "atom",
|
||||
},
|
||||
true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user