chore: all: use golang.org/x/exp/maps.(Keys, Values) where necessary (#13349)

Uses golang.org/x/exp/maps.(Keys, Values) to sort out flagged
potential non-determinism issues due to map iteration which is
randomized in maps.

These were flagged by cosmos/gosec in

* https://github.com/cosmos/cosmos-sdk/security/code-scanning/724
* https://github.com/cosmos/cosmos-sdk/security/code-scanning/725
* https://github.com/cosmos/cosmos-sdk/security/code-scanning/726
* https://github.com/cosmos/cosmos-sdk/security/code-scanning/727
* https://github.com/cosmos/cosmos-sdk/security/code-scanning/728
* https://github.com/cosmos/cosmos-sdk/security/code-scanning/729
* https://github.com/cosmos/cosmos-sdk/security/code-scanning/782
* https://github.com/cosmos/cosmos-sdk/security/code-scanning/813
* https://github.com/cosmos/cosmos-sdk/security/code-scanning/814
* https://github.com/cosmos/cosmos-sdk/security/code-scanning/816

which complained about potential non-determinism in
map iteration in which we only want appends in map iteration loops,
this change instead uses golang.org/x/exp/maps.Keys to retrieve
the keys then sort.Strings which simplifies the helper code.

This change fixes issues in:
* orm/model/ormdb: non-determinism in ExportJSON
* store/internal/proofs
* types/module
* x/auth/keeper
* x/bank
* x/genutil/client/cli

Fixes #13348
This commit is contained in:
Emmanuel T Odeke 2022-09-20 19:08:13 -07:00 committed by GitHub
parent 56a49aba46
commit 9c2aef342d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 37 additions and 38 deletions

View File

@ -49,6 +49,7 @@ require (
github.com/rogpeppe/go-internal v1.8.1 // indirect github.com/rogpeppe/go-internal v1.8.1 // indirect
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect
go.etcd.io/bbolt v1.3.6 // indirect go.etcd.io/bbolt v1.3.6 // indirect
golang.org/x/exp v0.0.0-20220916125017-b168a2c6b86b // indirect
golang.org/x/net v0.0.0-20220726230323-06994584191e // indirect golang.org/x/net v0.0.0-20220726230323-06994584191e // indirect
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab // indirect golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab // indirect
golang.org/x/text v0.3.7 // indirect golang.org/x/text v0.3.7 // indirect

View File

@ -165,6 +165,8 @@ golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnf
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/exp v0.0.0-20220916125017-b168a2c6b86b h1:SCE/18RnFsLrjydh/R/s5EVvHoZprqEQUuoxK8q2Pc4=
golang.org/x/exp v0.0.0-20220916125017-b168a2c6b86b/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=

View File

@ -5,20 +5,16 @@ import (
"fmt" "fmt"
"sort" "sort"
"github.com/cosmos/cosmos-sdk/orm/types/ormerrors" "golang.org/x/exp/maps"
"github.com/cosmos/cosmos-sdk/orm/types/ormjson"
"google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/reflect/protoreflect"
"cosmossdk.io/errors" "cosmossdk.io/errors"
"github.com/cosmos/cosmos-sdk/orm/types/ormerrors"
"github.com/cosmos/cosmos-sdk/orm/types/ormjson"
) )
func (m moduleDB) DefaultJSON(target ormjson.WriteTarget) error { func (m moduleDB) DefaultJSON(target ormjson.WriteTarget) error {
tableNames := make([]protoreflect.FullName, 0, len(m.tablesByName)) tableNames := maps.Keys(m.tablesByName)
for name := range m.tablesByName {
tableNames = append(tableNames, name)
}
sort.Slice(tableNames, func(i, j int) bool { sort.Slice(tableNames, func(i, j int) bool {
ti, tj := tableNames[i], tableNames[j] ti, tj := tableNames[i], tableNames[j]
return ti.Name() < tj.Name() return ti.Name() < tj.Name()
@ -113,12 +109,20 @@ func (m moduleDB) ImportJSON(ctx context.Context, source ormjson.ReadSource) err
} }
func (m moduleDB) ExportJSON(ctx context.Context, sink ormjson.WriteTarget) error { func (m moduleDB) ExportJSON(ctx context.Context, sink ormjson.WriteTarget) error {
for name, table := range m.tablesByName { // Ensure that we export the tables in a deterministic order.
tableNames := maps.Keys(m.tablesByName)
sort.Slice(tableNames, func(i, j int) bool {
ti, tj := tableNames[i], tableNames[j]
return ti.Name() < tj.Name()
})
for _, name := range tableNames {
w, err := sink.OpenWriter(name) w, err := sink.OpenWriter(name)
if err != nil { if err != nil {
return err return err
} }
table := m.tablesByName[name]
err = table.ExportJSON(ctx, w) err = table.ExportJSON(ctx, w)
if err != nil { if err != nil {
return err return err

View File

@ -5,6 +5,7 @@ import (
"github.com/tendermint/tendermint/libs/rand" "github.com/tendermint/tendermint/libs/rand"
tmcrypto "github.com/tendermint/tendermint/proto/tendermint/crypto" tmcrypto "github.com/tendermint/tendermint/proto/tendermint/crypto"
"golang.org/x/exp/maps"
sdkmaps "github.com/cosmos/cosmos-sdk/store/internal/maps" sdkmaps "github.com/cosmos/cosmos-sdk/store/internal/maps"
) )
@ -46,12 +47,7 @@ const (
) )
func SortedKeys(data map[string][]byte) []string { func SortedKeys(data map[string][]byte) []string {
keys := make([]string, len(data)) keys := maps.Keys(data)
i := 0
for k := range data {
keys[i] = k
i++
}
sort.Strings(keys) sort.Strings(keys)
return keys return keys
} }

View File

@ -36,6 +36,7 @@ import (
"github.com/grpc-ecosystem/grpc-gateway/runtime" "github.com/grpc-ecosystem/grpc-gateway/runtime"
"github.com/spf13/cobra" "github.com/spf13/cobra"
abci "github.com/tendermint/tendermint/abci/types" abci "github.com/tendermint/tendermint/abci/types"
"golang.org/x/exp/maps"
"github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/codec"
@ -118,7 +119,8 @@ func (bm BasicManager) RegisterGRPCGatewayRoutes(clientCtx client.Context, rtr *
// TODO: Remove clientCtx argument. // TODO: Remove clientCtx argument.
// REF: https://github.com/cosmos/cosmos-sdk/issues/6571 // REF: https://github.com/cosmos/cosmos-sdk/issues/6571
func (bm BasicManager) AddTxCommands(rootTxCmd *cobra.Command) { func (bm BasicManager) AddTxCommands(rootTxCmd *cobra.Command) {
for _, b := range bm { values := maps.Values(bm)
for _, b := range values {
if cmd := b.GetTxCmd(); cmd != nil { if cmd := b.GetTxCmd(); cmd != nil {
rootTxCmd.AddCommand(cmd) rootTxCmd.AddCommand(cmd)
} }
@ -130,7 +132,8 @@ func (bm BasicManager) AddTxCommands(rootTxCmd *cobra.Command) {
// TODO: Remove clientCtx argument. // TODO: Remove clientCtx argument.
// REF: https://github.com/cosmos/cosmos-sdk/issues/6571 // REF: https://github.com/cosmos/cosmos-sdk/issues/6571
func (bm BasicManager) AddQueryCommands(rootQueryCmd *cobra.Command) { func (bm BasicManager) AddQueryCommands(rootQueryCmd *cobra.Command) {
for _, b := range bm { values := maps.Values(bm)
for _, b := range values {
if cmd := b.GetQueryCmd(); cmd != nil { if cmd := b.GetQueryCmd(); cmd != nil {
rootQueryCmd.AddCommand(cmd) rootQueryCmd.AddCommand(cmd)
} }
@ -271,14 +274,16 @@ func (m *Manager) SetOrderMigrations(moduleNames ...string) {
// RegisterInvariants registers all module invariants // RegisterInvariants registers all module invariants
func (m *Manager) RegisterInvariants(ir sdk.InvariantRegistry) { func (m *Manager) RegisterInvariants(ir sdk.InvariantRegistry) {
for _, module := range m.Modules { modules := maps.Values(m.Modules)
for _, module := range modules {
module.RegisterInvariants(ir) module.RegisterInvariants(ir)
} }
} }
// RegisterServices registers all module services // RegisterServices registers all module services
func (m *Manager) RegisterServices(cfg Configurator) { func (m *Manager) RegisterServices(cfg Configurator) {
for _, module := range m.Modules { modules := maps.Values(m.Modules)
for _, module := range modules {
module.RegisterServices(cfg) module.RegisterServices(cfg)
} }
} }
@ -511,13 +516,7 @@ func (m *Manager) GetVersionMap() VersionMap {
// ModuleNames returns list of all module names, without any particular order. // ModuleNames returns list of all module names, without any particular order.
func (m *Manager) ModuleNames() []string { func (m *Manager) ModuleNames() []string {
ms := make([]string, len(m.Modules)) return maps.Keys(m.Modules)
i := 0
for m := range m.Modules {
ms[i] = m
i++
}
return ms
} }
// DefaultMigrationsOrder returns a default migrations order: ascending alphabetical by module name, // DefaultMigrationsOrder returns a default migrations order: ascending alphabetical by module name,

View File

@ -5,6 +5,7 @@ import (
gogotypes "github.com/cosmos/gogoproto/types" gogotypes "github.com/cosmos/gogoproto/types"
"github.com/tendermint/tendermint/libs/log" "github.com/tendermint/tendermint/libs/log"
"golang.org/x/exp/maps"
"github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/codec"
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
@ -80,8 +81,9 @@ func NewAccountKeeper(
maccPerms map[string][]string, bech32Prefix string, authority string, maccPerms map[string][]string, bech32Prefix string, authority string,
) AccountKeeper { ) AccountKeeper {
permAddrs := make(map[string]types.PermissionsForAddress) permAddrs := make(map[string]types.PermissionsForAddress)
for name, perms := range maccPerms { permNames := maps.Keys(maccPerms)
permAddrs[name] = types.NewPermissionsForAddress(name, perms) for _, name := range permNames {
permAddrs[name] = types.NewPermissionsForAddress(name, maccPerms[name])
} }
bech32Codec := newBech32Codec(bech32Prefix) bech32Codec := newBech32Codec(bech32Prefix)

View File

@ -12,6 +12,7 @@ import (
gwruntime "github.com/grpc-ecosystem/grpc-gateway/runtime" gwruntime "github.com/grpc-ecosystem/grpc-gateway/runtime"
"github.com/spf13/cobra" "github.com/spf13/cobra"
abci "github.com/tendermint/tendermint/abci/types" abci "github.com/tendermint/tendermint/abci/types"
"golang.org/x/exp/maps"
"github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/codec"
@ -236,7 +237,8 @@ func provideModule(in bankInputs) bankOutputs {
blockedAddresses[authtypes.NewModuleAddress(moduleName).String()] = true blockedAddresses[authtypes.NewModuleAddress(moduleName).String()] = true
} }
} else { } else {
for _, permission := range in.AccountKeeper.GetModulePermissions() { permissions := maps.Values(in.AccountKeeper.GetModulePermissions())
for _, permission := range permissions {
blockedAddresses[permission.GetAddress().String()] = true blockedAddresses[permission.GetAddress().String()] = true
} }
} }

View File

@ -9,6 +9,7 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/spf13/cobra" "github.com/spf13/cobra"
tmjson "github.com/tendermint/tendermint/libs/json" tmjson "github.com/tendermint/tendermint/libs/json"
"golang.org/x/exp/maps"
"github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/client/flags"
@ -38,15 +39,7 @@ func GetMigrationCallback(version string) types.MigrationCallback {
// GetMigrationVersions get all migration version in a sorted slice. // GetMigrationVersions get all migration version in a sorted slice.
func GetMigrationVersions() []string { func GetMigrationVersions() []string {
versions := make([]string, len(migrationMap)) versions := maps.Keys(migrationMap)
var i int
for version := range migrationMap {
versions[i] = version
i++
}
sort.Strings(versions) sort.Strings(versions)
return versions return versions