From 91e55428dc9b8cd5c341bb8f240f7d521a602857 Mon Sep 17 00:00:00 2001 From: Evgeniy Abramov Date: Wed, 18 Oct 2023 07:03:22 +0400 Subject: [PATCH] chore: some optimizations --- x/auth/keeper/genesis.go | 2 ++ x/params/types/subspace.go | 65 +++++++++++++++++++++++++++++++------- 2 files changed, 56 insertions(+), 11 deletions(-) diff --git a/x/auth/keeper/genesis.go b/x/auth/keeper/genesis.go index 0cc50f0aea13..94a9b6d09192 100644 --- a/x/auth/keeper/genesis.go +++ b/x/auth/keeper/genesis.go @@ -10,6 +10,8 @@ import ( // CONTRACT: old coins from the FeeCollectionKeeper need to be transferred through // a genesis port script to the new fee collector account func (ak AccountKeeper) InitGenesis(ctx sdk.Context, data types.GenesisState) { + ctx.Logger().Debug("AUTH#InitGenesis: start") + ak.SetParams(ctx, data.Params) ctx.Logger().Debug("AUTH#InitGenesis: running UnpackAccounts") diff --git a/x/params/types/subspace.go b/x/params/types/subspace.go index f90914f3a62a..b37d88fb64d2 100644 --- a/x/params/types/subspace.go +++ b/x/params/types/subspace.go @@ -3,6 +3,8 @@ package types import ( "fmt" "reflect" + "runtime" + "sync" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/store/prefix" @@ -251,19 +253,60 @@ func (s Subspace) GetParamSetIfExists(ctx sdk.Context, ps ParamSet) { // SetParamSet iterates through each ParamSetPair and sets the value with the // corresponding parameter key in the Subspace's KVStore. +// func (s Subspace) SetParamSet(ctx sdk.Context, ps ParamSet) { +// for _, pair := range ps.ParamSetPairs() { +// // pair.Field is a pointer to the field, so indirecting the ptr. +// // go-amino automatically handles it but just for sure, +// // since SetStruct is meant to be used in InitGenesis +// // so this method will not be called frequently +// v := reflect.Indirect(reflect.ValueOf(pair.Value)).Interface() + +// if err := pair.ValidatorFn(v); err != nil { +// panic(fmt.Sprintf("value from ParamSetPair is invalid: %s", err)) +// } + +// s.Set(ctx, pair.Key, v) +// } +// } + func (s Subspace) SetParamSet(ctx sdk.Context, ps ParamSet) { - for _, pair := range ps.ParamSetPairs() { - // pair.Field is a pointer to the field, so indirecting the ptr. - // go-amino automatically handles it but just for sure, - // since SetStruct is meant to be used in InitGenesis - // so this method will not be called frequently - v := reflect.Indirect(reflect.ValueOf(pair.Value)).Interface() - - if err := pair.ValidatorFn(v); err != nil { - panic(fmt.Sprintf("value from ParamSetPair is invalid: %s", err)) - } + pairs := ps.ParamSetPairs() + // Use number of CPU cores as a limit for concurrent goroutines + maxGoroutines := runtime.NumCPU() + sem := make(chan struct{}, maxGoroutines) + + var wg sync.WaitGroup + errorsChan := make(chan error, len(pairs)) + + for _, pair := range pairs { + wg.Add(1) + sem <- struct{}{} // Acquire a token + + go func(p ParamSetPair) { + defer wg.Done() + defer func() { <-sem }() // Release a token - s.Set(ctx, pair.Key, v) + // Process the pair + v := reflect.Indirect(reflect.ValueOf(p.Value)).Interface() + + if err := p.ValidatorFn(v); err != nil { + errorsChan <- fmt.Errorf("value from ParamSetPair is invalid: %s", err) + return + } + + s.Set(ctx, p.Key, v) + }(pair) + } + + // Wait for all goroutines to complete + wg.Wait() + close(errorsChan) + + // Handle any errors that occurred in the goroutines + for err := range errorsChan { + if err != nil { + panic(err) + } } }