Skip to content

Commit

Permalink
fix: orm/*, store/*: fix non-determinism from map iteration (cosmos#1…
Browse files Browse the repository at this point in the history
…2751)

Reported by informalsystems/gosec's map iteration pass, this
change fixes non-determinism from iterating with a map, whose
definition in the Go spec guarantees that the order of keys
and values presented during iteration will be randomized.

Fixes cosmos#12428
Fixes cosmos#12430
Fixes cosmos#12431
  • Loading branch information
odeke-em authored Jul 27, 2022
1 parent 37e765d commit 2f4faa5
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 3 deletions.
12 changes: 11 additions & 1 deletion orm/model/ormdb/json.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,17 @@ import (
)

func (m moduleDB) DefaultJSON(target ormjson.WriteTarget) error {
for name, table := range m.tablesByName {
tableNames := make([]protoreflect.FullName, 0, len(m.tablesByName))
for name := range m.tablesByName {
tableNames = append(tableNames, name)
}
sort.Slice(tableNames, func(i, j int) bool {
ti, tj := tableNames[i], tableNames[j]
return ti.Name() < tj.Name()
})

for _, name := range tableNames {
table := m.tablesByName[name]
w, err := target.OpenWriter(name)
if err != nil {
return err
Expand Down
12 changes: 11 additions & 1 deletion store/v2alpha1/multi/migration.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package multi

import (
"sort"

dbm "github.com/cosmos/cosmos-sdk/db"
"github.com/cosmos/cosmos-sdk/store/iavl"
"github.com/cosmos/cosmos-sdk/store/mem"
Expand All @@ -16,8 +18,16 @@ func MigrateFromV1(rootMultiStore *v1Store.Store, store2db dbm.Connection, store
*iavl.Store
name string
}
storeKeysByName := rootMultiStore.StoreKeysByName()
keys := make([]string, 0, len(storeKeysByName))
for key := range storeKeysByName {
keys = append(keys, key)
}
sort.Strings(keys)

var stores []namedStore
for _, storeKey := range rootMultiStore.StoreKeysByName() {
for _, key := range keys {
storeKey := storeKeysByName[key]
keyName := storeKey.Name()
switch store := rootMultiStore.GetStoreByName(keyName).(type) {
case *iavl.Store:
Expand Down
9 changes: 8 additions & 1 deletion store/v2alpha1/multi/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"io"
"math"
"sort"
"strings"
"sync"

Expand Down Expand Up @@ -327,8 +328,14 @@ func NewStore(db dbm.Connection, opts StoreConfig) (ret *Store, err error) {
if err != nil {
return
}
skeys := make([]string, 0, len(reg.StoreSchema))
for skey := range reg.StoreSchema {
skeys = append(skeys, skey)
}
sort.Strings(skeys)
// NB. the migrated contents and schema are not committed until the next store.Commit
for skey, typ := range reg.StoreSchema {
for _, skey := range skeys {
typ := reg.StoreSchema[skey]
err = schemaWriter.Set([]byte(skey), []byte{byte(typ)})
if err != nil {
return
Expand Down

0 comments on commit 2f4faa5

Please sign in to comment.