44 "fmt"
55 "io"
66 "maps"
7+ "sync"
78
89 "cosmossdk.io/store/tracekv"
910 "cosmossdk.io/store/types"
@@ -21,7 +22,10 @@ const storeNameCtxKey = "store_name"
2122// NOTE: a Store (and MultiStores in general) should never expose the
2223// keys for the substores.
2324type Store struct {
24- stores map [types.StoreKey ]types.CacheWrap
25+ // storesMut ensures concurrent callers (e.g. ExportGenesisForModules goroutines)
26+ // don't race when lazily creating substores.
27+ storesMut * sync.RWMutex
28+ stores map [types.StoreKey ]types.CacheWrap
2529
2630 traceWriter io.Writer
2731 traceContext types.TraceContext
@@ -38,6 +42,7 @@ func NewFromKVStore(
3842 traceWriter io.Writer , traceContext types.TraceContext ,
3943) Store {
4044 cms := Store {
45+ storesMut : & sync.RWMutex {},
4146 stores : make (map [types.StoreKey ]types.CacheWrap , len (stores )),
4247 traceWriter : traceWriter ,
4348 traceContext : traceContext ,
@@ -66,6 +71,7 @@ func NewFromParent(
6671 traceWriter io.Writer , traceContext types.TraceContext ,
6772) Store {
6873 return Store {
74+ storesMut : & sync.RWMutex {},
6975 stores : make (map [types.StoreKey ]types.CacheWrap ),
7076 traceWriter : traceWriter ,
7177 traceContext : traceContext ,
@@ -126,7 +132,12 @@ func (cms Store) GetStoreType() types.StoreType {
126132
127133// Write calls Write on each underlying store.
128134func (cms Store ) Write () {
129- for _ , store := range cms .stores {
135+ cms .storesMut .RLock ()
136+ stores := make (map [types.StoreKey ]types.CacheWrap , len (cms .stores ))
137+ maps .Copy (stores , cms .stores )
138+ cms .storesMut .RUnlock ()
139+
140+ for _ , store := range stores {
130141 store .Write ()
131142 }
132143}
@@ -157,6 +168,9 @@ func (cms Store) CacheMultiStoreWithVersion(_ int64) (types.CacheMultiStore, err
157168}
158169
159170func (cms Store ) getCacheWrapper (key types.StoreKey ) types.CacheWrapper {
171+ cms .storesMut .Lock ()
172+ defer cms .storesMut .Unlock ()
173+
160174 store , ok := cms .stores [key ]
161175 if ! ok && cms .parentStore != nil {
162176 // load on demand
0 commit comments