diff --git a/create-accounts.sh b/create-accounts.sh index 60d611bd6..b693207db 100755 --- a/create-accounts.sh +++ b/create-accounts.sh @@ -1,41 +1,52 @@ #!/bin/bash -TOTAL_ACCOUNTS=50000 -PARALLEL_JOBS=8 -ACCOUNTS_PER_JOB=$((TOTAL_ACCOUNTS / PARALLEL_JOBS)) - -create_accounts() { - local start=$1 - local end=$2 - local job_id=$3 - - for i in $(seq $start $end); do - if ! poktrolld keys add "app-$i" > /dev/null 2>&1; then - echo "Job $job_id: Error creating account app-$i" - continue - fi +TOTAL_ADDRESSES=${1:-50000} +PARALLEL_JOBS=${2:-8} +SEGMENTS_DIR="./segments" +OUTPUT_FILE="app_addresses.txt" + +create_segment() { + local job_id=$1 + local start_idx=$2 + local num_addresses=$3 + local segment_file="$SEGMENTS_DIR/segment_$job_id.txt" + + > "$segment_file" + for i in $(seq 0 $(($num_addresses-1))); do + addr_idx=$(($start_idx + $i + 1)) + output=$(poktrolld keys add "app-$addr_idx" --output json | jq -r .address 2>&1) + echo "$output" >> "$segment_file" + done +} - if [ $((i % 100)) -eq 0 ]; then - echo "Job $job_id: Progress $i/$end accounts created" +merge_segments() { + > "$OUTPUT_FILE" + for i in $(seq 0 $((PARALLEL_JOBS-1))); do + if [ -f "$SEGMENTS_DIR/segment_$i.txt" ]; then + cat "$SEGMENTS_DIR/segment_$i.txt" >> "$OUTPUT_FILE" + else + echo "Missing segment file: segment_$i.txt" >&2 + return 1 fi done } -echo "Starting parallel account creation with $PARALLEL_JOBS jobs..." +main() { + rm -rf $SEGMENTS_DIR + mkdir -p $SEGMENTS_DIR -# Launch parallel jobs -for job in $(seq 0 $((PARALLEL_JOBS-1))); do - start=$((job * ACCOUNTS_PER_JOB + 1)) - if [ $job -eq $((PARALLEL_JOBS-1)) ]; then - end=$TOTAL_ACCOUNTS - else - end=$((start + ACCOUNTS_PER_JOB - 1)) - fi + ADDRS_PER_JOB=$(( (TOTAL_ADDRESSES + PARALLEL_JOBS - 1) / PARALLEL_JOBS )) + echo "Creating $TOTAL_ADDRESSES addresses using $PARALLEL_JOBS parallel jobs" - create_accounts $start $end $job & -done + for job_id in $(seq 0 $((PARALLEL_JOBS-1))); do + start_idx=$((job_id * ADDRS_PER_JOB)) + create_segment "$job_id" "$start_idx" "$ADDRS_PER_JOB" & + done -# Wait for all background jobs to complete -wait + wait + merge_segments + rm -rf $SEGMENTS_DIR + echo "Complete - addresses written to $OUTPUT_FILE" +} -echo "All account creation jobs completed!" \ No newline at end of file +main \ No newline at end of file diff --git a/load-testing/tests/relays_stress_helpers_test.go b/load-testing/tests/relays_stress_helpers_test.go index 28b0b7163..48d8c352b 100644 --- a/load-testing/tests/relays_stress_helpers_test.go +++ b/load-testing/tests/relays_stress_helpers_test.go @@ -648,7 +648,9 @@ func (s *relaysSuite) createApplicationAccount( accAddress, err := keyRecord.GetAddress() require.NoError(s, err) - logger.Debug().Msgf("Application added %s", keyName) + if appIdx%5000 == 0 { + logger.Debug().Msgf("Application added %s", keyName) + } return &accountInfo{ address: accAddress.String(), diff --git a/stake_apps.sh b/stake_apps.sh index 292f9d9c8..637bd5af9 100755 --- a/stake_apps.sh +++ b/stake_apps.sh @@ -3,34 +3,22 @@ TOTAL_APPS=50000 PARALLEL_JOBS=8 CONFIG_DIR="localnet/poktrolld/config" -TEMP_DIR=/tmp/stake_apps SEGMENT_SIZE=$((TOTAL_APPS / PARALLEL_JOBS)) -# Create and setup temp directory -rm -rf $TEMP_DIR -mkdir -p $TEMP_DIR -chmod 777 $TEMP_DIR -trap 'rm -rf $TEMP_DIR' EXIT - # Function to process a segment of apps process_segment() { local start=$1 local end=$2 local job_id=$3 - local output="$TEMP_DIR/segment_$job_id.txt" local config_file="${CONFIG_DIR}/application_stake_config.yaml" echo "Job $job_id staking apps $start to $end" for i in $(seq $start $end); do local app_name="app-$i" - if poktrolld tx application stake-application -y \ + poktrolld tx application stake-application -y \ --config "$config_file" \ --keyring-backend test \ - --from "$app_name" > /dev/null 2>&1; then - echo "$app_name" >> "$output.success" - else - echo "$app_name" >> "$output.failed" - fi + --from "$app_name" > /dev/null 2>&1; done } @@ -50,22 +38,4 @@ done wait -# Report results -total_success=0 -total_failed=0 -for job_id in $(seq 0 $((PARALLEL_JOBS - 1))); do - if [ -f "$TEMP_DIR/segment_$job_id.txt.success" ]; then - success=$(wc -l < "$TEMP_DIR/segment_$job_id.txt.success") - total_success=$((total_success + success)) - fi - if [ -f "$TEMP_DIR/segment_$job_id.txt.failed" ]; then - failed=$(wc -l < "$TEMP_DIR/segment_$job_id.txt.failed") - total_failed=$((total_failed + failed)) - echo "Failed apps in job $job_id:" - cat "$TEMP_DIR/segment_$job_id.txt.failed" - fi -done - -echo "Staking complete!" -echo "Successfully staked: $total_success applications" -echo "Failed: $total_failed applications" \ No newline at end of file +echo "Staking complete!" \ No newline at end of file diff --git a/x/application/keeper/application.go b/x/application/keeper/application.go index e63ba8d18..6135d2c5c 100644 --- a/x/application/keeper/application.go +++ b/x/application/keeper/application.go @@ -12,14 +12,11 @@ import ( // SetApplication set a specific application in the store from its index func (k Keeper) SetApplication(ctx context.Context, application types.Application) { - if k.cache.Applications[application.Address] != nil { - k.cache.Applications[application.Address] = &application - } - storeAdapter := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)) store := prefix.NewStore(storeAdapter, types.KeyPrefix(types.ApplicationKeyPrefix)) appBz := k.cdc.MustMarshal(&application) store.Set(types.ApplicationKey(application.Address), appBz) + k.applicationsCache.Set(application.Address, application) } // GetApplication returns a application from its index @@ -27,9 +24,9 @@ func (k Keeper) GetApplication( ctx context.Context, appAddr string, ) (app types.Application, found bool) { - if app, found := k.cache.Applications[appAddr]; found { + if app, found := k.applicationsCache.Get(appAddr); found { k.logger.Info("-----Application cache hit-----") - return *app, true + return app, true } storeAdapter := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)) @@ -54,18 +51,17 @@ func (k Keeper) GetApplication( app.DelegateeGatewayAddresses = make([]string, 0) } - k.cache.Applications[appAddr] = &app + k.applicationsCache.Set(appAddr, app) return app, true } // RemoveApplication removes a application from the store func (k Keeper) RemoveApplication(ctx context.Context, appAddr string) { - delete(k.cache.Applications, appAddr) - storeAdapter := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)) store := prefix.NewStore(storeAdapter, types.KeyPrefix(types.ApplicationKeyPrefix)) store.Delete(types.ApplicationKey(appAddr)) + k.applicationsCache.Delete(appAddr) } // GetAllApplications returns all application @@ -86,7 +82,7 @@ func (k Keeper) GetAllApplications(ctx context.Context) (apps []types.Applicatio app.PendingUndelegations = make(map[uint64]types.UndelegatingGatewayList) } - k.cache.Applications[app.Address] = &app + k.applicationsCache.Set(app.Address, app) apps = append(apps, app) } diff --git a/x/application/keeper/keeper.go b/x/application/keeper/keeper.go index 7a55fbbe4..6432a89cf 100644 --- a/x/application/keeper/keeper.go +++ b/x/application/keeper/keeper.go @@ -9,6 +9,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/pokt-network/poktroll/x/application/types" + sharedtypes "github.com/pokt-network/poktroll/x/shared/types" ) type ( @@ -26,7 +27,8 @@ type ( gatewayKeeper types.GatewayKeeper sharedKeeper types.SharedKeeper - cache *types.Cache + applicationsCache *sharedtypes.Cache[string, types.Application] + paramsCache *sharedtypes.Cache[string, types.Params] } ) @@ -56,14 +58,14 @@ func NewKeeper( gatewayKeeper: gatewayKeeper, sharedKeeper: sharedKeeper, - cache: &types.Cache{ - Applications: make(map[string]*types.Application), - }, + applicationsCache: sharedtypes.NewCache[string, types.Application](), + paramsCache: sharedtypes.NewCache[string, types.Params](), } } func (k Keeper) ClearCache() { - k.cache.Clear() + k.applicationsCache.Clear() + k.paramsCache.Clear() } // GetAuthority returns the module's authority. diff --git a/x/application/keeper/params.go b/x/application/keeper/params.go index ecc58aacb..eece5c1d2 100644 --- a/x/application/keeper/params.go +++ b/x/application/keeper/params.go @@ -10,9 +10,9 @@ import ( // GetParams get all parameters as types.Params func (k Keeper) GetParams(ctx context.Context) (params types.Params) { - if k.cache.Params != nil { + if params, found := k.paramsCache.Get(""); found { k.logger.Info("-----Application params cache hit-----") - return *k.cache.Params + return params } store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)) @@ -22,21 +22,20 @@ func (k Keeper) GetParams(ctx context.Context) (params types.Params) { } k.cdc.MustUnmarshal(paramsBz, ¶ms) + k.paramsCache.Set("", params) - k.cache.Params = ¶ms return params } // SetParams set the params func (k Keeper) SetParams(ctx context.Context, params types.Params) error { - k.cache.Params = ¶ms - store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)) paramsBz, err := k.cdc.Marshal(¶ms) if err != nil { return err } store.Set(types.ParamsKey, paramsBz) + k.paramsCache.Set("", params) return nil } diff --git a/x/application/types/cache.go b/x/application/types/cache.go deleted file mode 100644 index c87030175..000000000 --- a/x/application/types/cache.go +++ /dev/null @@ -1,11 +0,0 @@ -package types - -type Cache struct { - Params *Params - Applications map[string]*Application -} - -func (c *Cache) Clear() { - c.Params = nil - clear(c.Applications) -} diff --git a/x/proof/keeper/claim.go b/x/proof/keeper/claim.go index c1a305197..600bdb0fd 100644 --- a/x/proof/keeper/claim.go +++ b/x/proof/keeper/claim.go @@ -22,8 +22,7 @@ func (k Keeper) UpsertClaim(ctx context.Context, claim types.Claim) { sessionId := claim.GetSessionHeader().GetSessionId() primaryKey := types.ClaimPrimaryKey(sessionId, claim.SupplierOperatorAddress) primaryStore.Set(primaryKey, claimBz) - - k.cache.Claims[sessionId] = &claim + k.claimsCache.Set(string(primaryKey), claim) logger.Info(fmt.Sprintf("upserted claim for supplier %s with primaryKey %s", claim.SupplierOperatorAddress, primaryKey)) @@ -43,14 +42,15 @@ func (k Keeper) UpsertClaim(ctx context.Context, claim types.Claim) { // GetClaim returns a claim from its index func (k Keeper) GetClaim(ctx context.Context, sessionId, supplierOperatorAddr string) (_ types.Claim, isClaimFound bool) { - if claim, found := k.cache.Claims[sessionId]; found { + primaryKey := types.ClaimPrimaryKey(sessionId, supplierOperatorAddr) + if claim, found := k.claimsCache.Get(string(primaryKey)); found { k.logger.Info("-----Supplier cache hit-----") - return *claim, true + return claim, true } - claim, found := k.getClaimByPrimaryKey(ctx, types.ClaimPrimaryKey(sessionId, supplierOperatorAddr)) + claim, found := k.getClaimByPrimaryKey(ctx, primaryKey) if found { - k.cache.Claims[sessionId] = &claim + k.claimsCache.Set(string(primaryKey), claim) } return claim, found @@ -65,7 +65,6 @@ func (k Keeper) RemoveClaim(ctx context.Context, sessionId, supplierOperatorAddr // Check if the claim exists primaryKey := types.ClaimPrimaryKey(sessionId, supplierOperatorAddr) - delete(k.cache.Claims, sessionId) foundClaim, isClaimFound := k.getClaimByPrimaryKey(ctx, primaryKey) if !isClaimFound { logger.Error(fmt.Sprintf("trying to delete non-existent claim with primary key %s for supplier %s and session %s", primaryKey, supplierOperatorAddr, sessionId)) @@ -84,6 +83,7 @@ func (k Keeper) RemoveClaim(ctx context.Context, sessionId, supplierOperatorAddr primaryStore.Delete(primaryKey) supplierOperatorAddrStore.Delete(supplierOperatorAddrKey) sessionEndHeightStore.Delete(sessionEndHeightKey) + k.claimsCache.Delete(string(primaryKey)) logger.Info(fmt.Sprintf("deleted claim with primary key %s for supplier %s and session %s", primaryKey, supplierOperatorAddr, sessionId)) } @@ -99,7 +99,7 @@ func (k Keeper) GetAllClaims(ctx context.Context) (claims []types.Claim) { for ; iterator.Valid(); iterator.Next() { var claim types.Claim k.cdc.MustUnmarshal(iterator.Value(), &claim) - k.cache.Claims[claim.GetSessionHeader().GetSessionId()] = &claim + k.claimsCache.Set(string(iterator.Key()), claim) claims = append(claims, claim) } diff --git a/x/proof/keeper/keeper.go b/x/proof/keeper/keeper.go index 7a802cc95..e5d2920ee 100644 --- a/x/proof/keeper/keeper.go +++ b/x/proof/keeper/keeper.go @@ -16,6 +16,7 @@ import ( "github.com/pokt-network/poktroll/pkg/polylog" _ "github.com/pokt-network/poktroll/pkg/polylog/polyzero" "github.com/pokt-network/poktroll/x/proof/types" + sharedtypes "github.com/pokt-network/poktroll/x/shared/types" ) type ( @@ -39,7 +40,9 @@ type ( accountQuerier client.AccountQueryClient sharedQuerier client.SharedQueryClient - cache *types.Cache + claimsCache *sharedtypes.Cache[string, types.Claim] + proofsCache *sharedtypes.Cache[string, types.Proof] + paramsCache *sharedtypes.Cache[string, types.Params] } ) @@ -104,15 +107,16 @@ func NewKeeper( accountQuerier: accountQuerier, sharedQuerier: sharedQuerier, - cache: &types.Cache{ - Proofs: make(map[string]*types.Proof), - Claims: make(map[string]*types.Claim), - }, + claimsCache: sharedtypes.NewCache[string, types.Claim](), + proofsCache: sharedtypes.NewCache[string, types.Proof](), + paramsCache: sharedtypes.NewCache[string, types.Params](), } } func (k Keeper) ClearCache() { - k.cache.Clear() + k.claimsCache.Clear() + k.proofsCache.Clear() + k.paramsCache.Clear() k.accountQuerier.ClearCache() } diff --git a/x/proof/keeper/params.go b/x/proof/keeper/params.go index 521fefe96..9c416c97f 100644 --- a/x/proof/keeper/params.go +++ b/x/proof/keeper/params.go @@ -10,9 +10,9 @@ import ( // GetParams get all parameters as types.Params func (k Keeper) GetParams(ctx context.Context) (params types.Params) { - if k.cache.Params != nil { + if params, found := k.paramsCache.Get(""); found { k.logger.Info("-----Proof params cache hit-----") - return *k.cache.Params + return params } store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)) @@ -22,20 +22,19 @@ func (k Keeper) GetParams(ctx context.Context) (params types.Params) { } k.cdc.MustUnmarshal(paramsBz, ¶ms) - k.cache.Params = ¶ms + k.paramsCache.Set("", params) return params } // SetParams set the params func (k Keeper) SetParams(ctx context.Context, params types.Params) error { - k.cache.Params = ¶ms - store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)) paramsBz, err := k.cdc.Marshal(¶ms) if err != nil { return err } store.Set(types.ParamsKey, paramsBz) + k.paramsCache.Set("", params) return nil } diff --git a/x/proof/keeper/proof.go b/x/proof/keeper/proof.go index 0bcaf60b6..207fb1416 100644 --- a/x/proof/keeper/proof.go +++ b/x/proof/keeper/proof.go @@ -23,8 +23,6 @@ func (k Keeper) UpsertProof(ctx context.Context, proof types.Proof) { primaryKey := types.ProofPrimaryKey(sessionId, proof.GetSupplierOperatorAddress()) primaryStore.Set(primaryKey, proofBz) - k.cache.Proofs[sessionId] = &proof - logger.Info( fmt.Sprintf("upserted proof for supplier %s with primaryKey %s", proof.GetSupplierOperatorAddress(), primaryKey), ) @@ -41,18 +39,20 @@ func (k Keeper) UpsertProof(ctx context.Context, proof types.Proof) { sessionEndHeight := proof.GetSessionHeader().GetSessionEndBlockHeight() sessionEndHeightKey := types.ProofSupplierEndSessionHeightKey(sessionEndHeight, primaryKey) sessionEndHeightStore.Set(sessionEndHeightKey, primaryKey) + k.proofsCache.Set(string(primaryKey), proof) } // GetProof returns a proof from its index func (k Keeper) GetProof(ctx context.Context, sessionId, supplierOperatorAddr string) (_ types.Proof, isProofFound bool) { - if proof, found := k.cache.Proofs[sessionId]; found { + primaryKey := types.ProofPrimaryKey(sessionId, supplierOperatorAddr) + if proof, found := k.proofsCache.Get(string(primaryKey)); found { k.logger.Info("-----Proof cache hit-----") - return *proof, true + return proof, true } - proof, found := k.getProofByPrimaryKey(ctx, types.ProofPrimaryKey(sessionId, supplierOperatorAddr)) + proof, found := k.getProofByPrimaryKey(ctx, primaryKey) if found { - k.cache.Proofs[sessionId] = &proof + k.proofsCache.Set(string(primaryKey), proof) } return proof, found @@ -67,7 +67,6 @@ func (k Keeper) RemoveProof(ctx context.Context, sessionId, supplierOperatorAddr // Check if the proof exists primaryKey := types.ProofPrimaryKey(sessionId, supplierOperatorAddr) - delete(k.cache.Proofs, sessionId) foundProof, isProofFound := k.getProofByPrimaryKey(ctx, primaryKey) if !isProofFound { logger.Error( @@ -78,6 +77,7 @@ func (k Keeper) RemoveProof(ctx context.Context, sessionId, supplierOperatorAddr sessionId, ), ) + k.proofsCache.Delete(string(primaryKey)) return } @@ -93,6 +93,7 @@ func (k Keeper) RemoveProof(ctx context.Context, sessionId, supplierOperatorAddr primaryStore.Delete(primaryKey) supplierOperatorAddrStore.Delete(supplierOperatorAddrKey) sessionEndHeightStore.Delete(sessionEndHeightKey) + k.proofsCache.Delete(string(primaryKey)) logger.Info( fmt.Sprintf( @@ -120,7 +121,7 @@ func (k Keeper) GetAllProofs(ctx context.Context) (proofs []types.Proof) { for ; iterator.Valid(); iterator.Next() { var proof types.Proof k.cdc.MustUnmarshal(iterator.Value(), &proof) - k.cache.Proofs[proof.GetSessionHeader().GetSessionId()] = &proof + k.proofsCache.Set(string(iterator.Key()), proof) proofs = append(proofs, proof) } diff --git a/x/proof/types/account_query_client.go b/x/proof/types/account_query_client.go index 65da7061c..2ce4fa58c 100644 --- a/x/proof/types/account_query_client.go +++ b/x/proof/types/account_query_client.go @@ -3,6 +3,7 @@ package types import ( "context" fmt "fmt" + "sync" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" "github.com/cosmos/cosmos-sdk/types" @@ -18,6 +19,7 @@ var _ client.AccountQueryClient = (*AccountKeeperQueryClient)(nil) type AccountKeeperQueryClient struct { keeper AccountKeeper accountPubKeyCache map[string]cryptotypes.PubKey + CacheMu *sync.RWMutex } // NewAccountKeeperQueryClient returns a new AccountQueryClient that is backed @@ -29,6 +31,7 @@ func NewAccountKeeperQueryClient(accountKeeper AccountKeeper) client.AccountQuer return &AccountKeeperQueryClient{ keeper: accountKeeper, accountPubKeyCache: make(map[string]cryptotypes.PubKey), + CacheMu: &sync.RWMutex{}, } } @@ -63,6 +66,8 @@ func (accountQueryClient *AccountKeeperQueryClient) GetPubKeyFromAddress( ctx context.Context, address string, ) (cryptotypes.PubKey, error) { + accountQueryClient.CacheMu.RLock() + defer accountQueryClient.CacheMu.RUnlock() if acc, found := accountQueryClient.accountPubKeyCache[address]; found { fmt.Println("-----PubKey cache hit-----") return acc, nil @@ -88,5 +93,7 @@ func (accountQueryClient *AccountKeeperQueryClient) GetPubKeyFromAddress( } func (accountQueryClient *AccountKeeperQueryClient) ClearCache() { + accountQueryClient.CacheMu.Lock() + defer accountQueryClient.CacheMu.Unlock() clear(accountQueryClient.accountPubKeyCache) } diff --git a/x/proof/types/cache.go b/x/proof/types/cache.go deleted file mode 100644 index 42c2bc010..000000000 --- a/x/proof/types/cache.go +++ /dev/null @@ -1,13 +0,0 @@ -package types - -type Cache struct { - Params *Params - Claims map[string]*Claim - Proofs map[string]*Proof -} - -func (c *Cache) Clear() { - c.Params = nil - clear(c.Claims) - clear(c.Proofs) -} diff --git a/x/service/keeper/keeper.go b/x/service/keeper/keeper.go index b7ec31bfd..56174c976 100644 --- a/x/service/keeper/keeper.go +++ b/x/service/keeper/keeper.go @@ -24,7 +24,9 @@ type ( bankKeeper types.BankKeeper - cache *types.Cache + servicesCache *sharedtypes.Cache[string, sharedtypes.Service] + relayMiningDifficultyCache *sharedtypes.Cache[string, types.RelayMiningDifficulty] + paramsCache *sharedtypes.Cache[string, types.Params] } ) @@ -48,15 +50,16 @@ func NewKeeper( bankKeeper: bankKeeper, - cache: &types.Cache{ - Services: make(map[string]*sharedtypes.Service), - RelayMiningDifficulty: make(map[string]*types.RelayMiningDifficulty), - }, + servicesCache: sharedtypes.NewCache[string, sharedtypes.Service](), + relayMiningDifficultyCache: sharedtypes.NewCache[string, types.RelayMiningDifficulty](), + paramsCache: sharedtypes.NewCache[string, types.Params](), } } func (k Keeper) ClearCache() { - k.cache.Clear() + k.servicesCache.Clear() + k.relayMiningDifficultyCache.Clear() + k.paramsCache.Clear() } // GetAuthority returns the module's authority. diff --git a/x/service/keeper/params.go b/x/service/keeper/params.go index 840c34f4c..d2e366853 100644 --- a/x/service/keeper/params.go +++ b/x/service/keeper/params.go @@ -10,9 +10,9 @@ import ( // GetParams get all parameters as types.Params func (k Keeper) GetParams(ctx context.Context) (params types.Params) { - if k.cache.Params != nil { + if params, found := k.paramsCache.Get(""); found { k.logger.Info("-----Service params cache hit-----") - return *k.cache.Params + return params } store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)) @@ -22,20 +22,19 @@ func (k Keeper) GetParams(ctx context.Context) (params types.Params) { } k.cdc.MustUnmarshal(paramsBz, ¶ms) - k.cache.Params = ¶ms + k.paramsCache.Set("", params) return params } // SetParams set the params func (k Keeper) SetParams(ctx context.Context, params types.Params) error { - k.cache.Params = ¶ms - store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)) paramsBz, err := k.cdc.Marshal(¶ms) if err != nil { return err } store.Set(types.ParamsKey, paramsBz) + k.paramsCache.Set("", params) return nil } diff --git a/x/service/keeper/relay_mining_difficulty.go b/x/service/keeper/relay_mining_difficulty.go index 9da817acc..70ae47701 100644 --- a/x/service/keeper/relay_mining_difficulty.go +++ b/x/service/keeper/relay_mining_difficulty.go @@ -13,13 +13,13 @@ import ( // SetRelayMiningDifficulty set a specific relayMiningDifficulty in the store from its index func (k Keeper) SetRelayMiningDifficulty(ctx context.Context, relayMiningDifficulty types.RelayMiningDifficulty) { - k.cache.RelayMiningDifficulty[relayMiningDifficulty.ServiceId] = &relayMiningDifficulty storeAdapter := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)) store := prefix.NewStore(storeAdapter, types.KeyPrefix(types.RelayMiningDifficultyKeyPrefix)) difficultyBz := k.cdc.MustMarshal(&relayMiningDifficulty) store.Set(types.RelayMiningDifficultyKey( relayMiningDifficulty.ServiceId, ), difficultyBz) + k.relayMiningDifficultyCache.Set(relayMiningDifficulty.ServiceId, relayMiningDifficulty) } // GetRelayMiningDifficulty returns a relayMiningDifficulty from its index @@ -27,9 +27,9 @@ func (k Keeper) GetRelayMiningDifficulty( ctx context.Context, serviceId string, ) (difficulty types.RelayMiningDifficulty, found bool) { - if difficulty, found := k.cache.RelayMiningDifficulty[serviceId]; found { + if difficulty, found := k.relayMiningDifficultyCache.Get(serviceId); found { k.logger.Info("-----Difficulty cache hit-----") - return *difficulty, true + return difficulty, true } storeAdapter := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)) store := prefix.NewStore(storeAdapter, types.KeyPrefix(types.RelayMiningDifficultyKeyPrefix)) @@ -52,7 +52,7 @@ func (k Keeper) GetRelayMiningDifficulty( } k.cdc.MustUnmarshal(difficultyBz, &difficulty) - k.cache.RelayMiningDifficulty[serviceId] = &difficulty + k.relayMiningDifficultyCache.Set(serviceId, difficulty) return difficulty, true } @@ -63,8 +63,6 @@ func (k Keeper) RemoveRelayMiningDifficulty( ) { logger := k.Logger().With("method", "RemoveRelayMiningDifficulty") - delete(k.cache.RelayMiningDifficulty, serviceId) - storeAdapter := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)) store := prefix.NewStore(storeAdapter, types.KeyPrefix(types.RelayMiningDifficultyKeyPrefix)) difficultyKey := types.RelayMiningDifficultyKey( @@ -79,6 +77,7 @@ func (k Keeper) RemoveRelayMiningDifficulty( store.Delete(types.RelayMiningDifficultyKey( serviceId, )) + k.relayMiningDifficultyCache.Delete(serviceId) } // GetAllRelayMiningDifficulty returns all relayMiningDifficulty @@ -92,7 +91,7 @@ func (k Keeper) GetAllRelayMiningDifficulty(ctx context.Context) (list []types.R for ; iterator.Valid(); iterator.Next() { var difficulty types.RelayMiningDifficulty k.cdc.MustUnmarshal(iterator.Value(), &difficulty) - k.cache.RelayMiningDifficulty[difficulty.ServiceId] = &difficulty + k.relayMiningDifficultyCache.Set(difficulty.ServiceId, difficulty) list = append(list, difficulty) } diff --git a/x/service/keeper/service.go b/x/service/keeper/service.go index 2ccee3dc2..94bf9ecd4 100644 --- a/x/service/keeper/service.go +++ b/x/service/keeper/service.go @@ -13,11 +13,11 @@ import ( // SetService set a specific service in the store from its index func (k Keeper) SetService(ctx context.Context, service sharedtypes.Service) { - k.cache.Services[service.Id] = &service storeAdapter := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)) store := prefix.NewStore(storeAdapter, types.KeyPrefix(types.ServiceKeyPrefix)) serviceBz := k.cdc.MustMarshal(&service) store.Set(types.ServiceKey(service.Id), serviceBz) + k.servicesCache.Set(service.Id, service) } // GetService returns a service from its index @@ -25,9 +25,9 @@ func (k Keeper) GetService( ctx context.Context, serviceId string, ) (service sharedtypes.Service, found bool) { - if service, found := k.cache.Services[service.Id]; found { + if service, found := k.servicesCache.Get(serviceId); found { k.logger.Info("-----Service cache hit-----") - return *service, true + return service, true } storeAdapter := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)) store := prefix.NewStore(storeAdapter, types.KeyPrefix(types.ServiceKeyPrefix)) @@ -38,7 +38,7 @@ func (k Keeper) GetService( } k.cdc.MustUnmarshal(serviceBz, &service) - k.cache.Services[service.Id] = &service + k.servicesCache.Set(serviceId, service) return service, true } @@ -47,10 +47,10 @@ func (k Keeper) RemoveService( ctx context.Context, serviceId string, ) { - delete(k.cache.Services, serviceId) storeAdapter := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)) store := prefix.NewStore(storeAdapter, types.KeyPrefix(types.ServiceKeyPrefix)) store.Delete(types.ServiceKey(serviceId)) + k.servicesCache.Delete(serviceId) } // GetAllServices returns all services @@ -64,7 +64,7 @@ func (k Keeper) GetAllServices(ctx context.Context) (services []sharedtypes.Serv for ; iterator.Valid(); iterator.Next() { var service sharedtypes.Service k.cdc.MustUnmarshal(iterator.Value(), &service) - k.cache.Services[service.Id] = &service + k.servicesCache.Set(service.Id, service) services = append(services, service) } diff --git a/x/service/types/cache.go b/x/service/types/cache.go deleted file mode 100644 index 0819e9038..000000000 --- a/x/service/types/cache.go +++ /dev/null @@ -1,15 +0,0 @@ -package types - -import sharedtypes "github.com/pokt-network/poktroll/x/shared/types" - -type Cache struct { - Params *Params - Services map[string]*sharedtypes.Service - RelayMiningDifficulty map[string]*RelayMiningDifficulty -} - -func (c *Cache) Clear() { - c.Params = nil - clear(c.Services) - clear(c.RelayMiningDifficulty) -} diff --git a/x/session/keeper/block_hash.go b/x/session/keeper/block_hash.go index 974773131..f0ad1e711 100644 --- a/x/session/keeper/block_hash.go +++ b/x/session/keeper/block_hash.go @@ -11,7 +11,7 @@ import ( // GetBlockHash returns the hash of the block at the given height. func (k Keeper) GetBlockHash(ctx context.Context, height int64) []byte { - if hash, found := k.cache.BlockHashes[height]; found { + if hash, found := k.blockHashesCache.Get(height); found { k.logger.Info("-----Blockhash cache hit-----") return hash } @@ -24,10 +24,11 @@ func (k Keeper) GetBlockHash(ctx context.Context, height int64) []byte { storeAdapter := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)) store := prefix.NewStore(storeAdapter, types.KeyPrefix(types.BlockHashKeyPrefix)) blockHash := store.Get(types.BlockHashKey(height)) - k.cache.BlockHashes[height] = blockHash + k.blockHashesCache.Set(height, blockHash) return blockHash } func (k Keeper) ClearCache() { - k.cache.Clear() + k.blockHashesCache.Clear() + k.paramsCache.Clear() } diff --git a/x/session/keeper/keeper.go b/x/session/keeper/keeper.go index 7399fcec3..9a2884197 100644 --- a/x/session/keeper/keeper.go +++ b/x/session/keeper/keeper.go @@ -12,6 +12,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/pokt-network/poktroll/x/session/types" + sharedtypes "github.com/pokt-network/poktroll/x/shared/types" ) type ( @@ -30,7 +31,8 @@ type ( supplierKeeper types.SupplierKeeper sharedKeeper types.SharedKeeper - cache *types.Cache + blockHashesCache *sharedtypes.Cache[int64, []byte] + paramsCache *sharedtypes.Cache[string, types.Params] } ) @@ -62,9 +64,8 @@ func NewKeeper( supplierKeeper: supplierKeeper, sharedKeeper: sharedKeeper, - cache: &types.Cache{ - BlockHashes: make(map[int64][]byte), - }, + blockHashesCache: sharedtypes.NewCache[int64, []byte](), + paramsCache: sharedtypes.NewCache[string, types.Params](), } } @@ -90,7 +91,7 @@ func (k Keeper) StoreBlockHash(goCtx context.Context) { // ctx.BlocHeight() is the height of the block being validated. height := ctx.BlockHeight() - k.cache.BlockHashes[height] = hash + k.blockHashesCache.Set(height, hash) storeAdapter := runtime.KVStoreAdapter(k.storeService.OpenKVStore(goCtx)) store := prefix.NewStore(storeAdapter, types.KeyPrefix(types.BlockHashKeyPrefix)) diff --git a/x/session/keeper/params.go b/x/session/keeper/params.go index f2c3b0a23..5ec9da118 100644 --- a/x/session/keeper/params.go +++ b/x/session/keeper/params.go @@ -10,9 +10,9 @@ import ( // GetParams get all parameters as types.Params func (k Keeper) GetParams(ctx context.Context) (params types.Params) { - if k.cache.Params != nil { + if params, found := k.paramsCache.Get(""); found { k.logger.Info("-----Session params cache hit-----") - return *k.cache.Params + return params } store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)) @@ -22,20 +22,19 @@ func (k Keeper) GetParams(ctx context.Context) (params types.Params) { } k.cdc.MustUnmarshal(paramsBz, ¶ms) - k.cache.Params = ¶ms + k.paramsCache.Set("", params) return params } // SetParams set the params func (k Keeper) SetParams(ctx context.Context, params types.Params) error { - k.cache.Params = ¶ms - store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)) paramsBz, err := k.cdc.Marshal(¶ms) if err != nil { return err } store.Set(types.ParamsKey, paramsBz) + k.paramsCache.Set("", params) return nil } diff --git a/x/session/types/cache.go b/x/session/types/cache.go deleted file mode 100644 index 24c19be58..000000000 --- a/x/session/types/cache.go +++ /dev/null @@ -1,11 +0,0 @@ -package types - -type Cache struct { - BlockHashes map[int64][]byte - Params *Params -} - -func (c *Cache) Clear() { - c.Params = nil - clear(c.BlockHashes) -} diff --git a/x/shared/keeper/keeper.go b/x/shared/keeper/keeper.go index 13dbf3a9b..ef5441a7c 100644 --- a/x/shared/keeper/keeper.go +++ b/x/shared/keeper/keeper.go @@ -21,7 +21,7 @@ type ( // should be the x/gov module account. authority string - cache *types.Cache + paramsCache *types.Cache[string, types.Params] } ) @@ -42,7 +42,7 @@ func NewKeeper( authority: authority, logger: logger, - cache: &types.Cache{}, + paramsCache: types.NewCache[string, types.Params](), } } diff --git a/x/shared/keeper/params.go b/x/shared/keeper/params.go index 70e31a121..8233eabc0 100644 --- a/x/shared/keeper/params.go +++ b/x/shared/keeper/params.go @@ -10,9 +10,9 @@ import ( // GetParams get all parameters as types.Params func (k Keeper) GetParams(ctx context.Context) (params types.Params) { - if k.cache.Params != nil { + if params, found := k.paramsCache.Get(""); found { k.logger.Info("-----Shared params cache hit-----") - return *k.cache.Params + return params } store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)) @@ -22,24 +22,23 @@ func (k Keeper) GetParams(ctx context.Context) (params types.Params) { } k.cdc.MustUnmarshal(bz, ¶ms) - k.cache.Params = ¶ms + k.paramsCache.Set("", params) return params } // SetParams set the params func (k Keeper) SetParams(ctx context.Context, params types.Params) error { - k.cache.Params = ¶ms - store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)) bz, err := k.cdc.Marshal(¶ms) if err != nil { return err } store.Set(types.ParamsKey, bz) + k.paramsCache.Set("", params) return nil } func (k Keeper) ClearCache() { - k.cache.Clear() + k.paramsCache.Clear() } diff --git a/x/shared/types/cache.go b/x/shared/types/cache.go index cee8c58b8..e1db4eebc 100644 --- a/x/shared/types/cache.go +++ b/x/shared/types/cache.go @@ -1,9 +1,40 @@ package types -type Cache struct { - Params *Params +import "sync" + +type Cache[K comparable, V any] struct { + store map[K]V + cacheMu *sync.RWMutex +} + +func (c *Cache[K, V]) Get(key K) (V, bool) { + c.cacheMu.RLock() + defer c.cacheMu.RUnlock() + val, ok := c.store[key] + return val, ok +} + +func (c *Cache[K, V]) Set(key K, val V) { + c.cacheMu.Lock() + defer c.cacheMu.Unlock() + c.store[key] = val +} + +func (c *Cache[K, V]) Delete(key K) { + c.cacheMu.Lock() + defer c.cacheMu.Unlock() + delete(c.store, key) +} + +func (c *Cache[K, V]) Clear() { + c.cacheMu.Lock() + defer c.cacheMu.Unlock() + clear(c.store) } -func (c *Cache) Clear() { - c.Params = nil +func NewCache[K comparable, V any]() *Cache[K, V] { + return &Cache[K, V]{ + store: make(map[K]V), + cacheMu: &sync.RWMutex{}, + } } diff --git a/x/supplier/keeper/keeper.go b/x/supplier/keeper/keeper.go index 073e57664..9825fb41f 100644 --- a/x/supplier/keeper/keeper.go +++ b/x/supplier/keeper/keeper.go @@ -26,7 +26,8 @@ type ( sharedKeeper types.SharedKeeper serviceKeeper types.ServiceKeeper - cache types.Cache + suppliersCache *sharedtypes.Cache[string, sharedtypes.Supplier] + paramsCache *sharedtypes.Cache[string, types.Params] } ) @@ -54,9 +55,8 @@ func NewKeeper( sharedKeeper: sharedKeeper, serviceKeeper: serviceKeeper, - cache: types.Cache{ - Suppliers: make(map[string]*sharedtypes.Supplier), - }, + suppliersCache: sharedtypes.NewCache[string, sharedtypes.Supplier](), + paramsCache: sharedtypes.NewCache[string, types.Params](), } } diff --git a/x/supplier/keeper/params.go b/x/supplier/keeper/params.go index a64416dd7..c6489c2c3 100644 --- a/x/supplier/keeper/params.go +++ b/x/supplier/keeper/params.go @@ -10,9 +10,9 @@ import ( // GetParams get all parameters as types.Params func (k Keeper) GetParams(ctx context.Context) (params types.Params) { - if k.cache.Params != nil { + if params, found := k.paramsCache.Get(""); found { k.logger.Info("-----Supplier params cache hit-----") - return *k.cache.Params + return params } store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)) @@ -22,19 +22,19 @@ func (k Keeper) GetParams(ctx context.Context) (params types.Params) { } k.cdc.MustUnmarshal(paramsBz, ¶ms) - k.cache.Params = ¶ms + k.paramsCache.Set("", params) return params } // SetParams set the params func (k Keeper) SetParams(ctx context.Context, params types.Params) error { - k.cache.Params = ¶ms store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)) paramsBz, err := k.cdc.Marshal(¶ms) if err != nil { return err } store.Set(types.ParamsKey, paramsBz) + k.paramsCache.Set("", params) return nil } diff --git a/x/supplier/keeper/supplier.go b/x/supplier/keeper/supplier.go index 8b9aa8ff6..70ab976ab 100644 --- a/x/supplier/keeper/supplier.go +++ b/x/supplier/keeper/supplier.go @@ -13,13 +13,13 @@ import ( // SetSupplier set a specific supplier in the store from its index func (k Keeper) SetSupplier(ctx context.Context, supplier sharedtypes.Supplier) { - k.cache.Suppliers[supplier.OperatorAddress] = &supplier storeAdapter := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)) store := prefix.NewStore(storeAdapter, types.KeyPrefix(types.SupplierKeyOperatorPrefix)) supplierBz := k.cdc.MustMarshal(&supplier) store.Set(types.SupplierOperatorKey( supplier.OperatorAddress, ), supplierBz) + k.suppliersCache.Set(supplier.OperatorAddress, supplier) } // GetSupplier returns a supplier from its index @@ -27,9 +27,9 @@ func (k Keeper) GetSupplier( ctx context.Context, supplierOperatorAddr string, ) (supplier sharedtypes.Supplier, found bool) { - if supplier, found := k.cache.Suppliers[supplierOperatorAddr]; found { + if supplier, found := k.suppliersCache.Get(supplierOperatorAddr); found { k.logger.Info("-----Supplier cache hit-----") - return *supplier, true + return supplier, true } storeAdapter := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)) @@ -41,16 +41,16 @@ func (k Keeper) GetSupplier( } k.cdc.MustUnmarshal(supplierBz, &supplier) - k.cache.Suppliers[supplier.OperatorAddress] = &supplier + k.suppliersCache.Set(supplier.OperatorAddress, supplier) return supplier, true } // RemoveSupplier removes a supplier from the store func (k Keeper) RemoveSupplier(ctx context.Context, supplierOperatorAddress string) { - delete(k.cache.Suppliers, supplierOperatorAddress) storeAdapter := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)) store := prefix.NewStore(storeAdapter, types.KeyPrefix(types.SupplierKeyOperatorPrefix)) store.Delete(types.SupplierOperatorKey(supplierOperatorAddress)) + k.suppliersCache.Delete(supplierOperatorAddress) } // GetAllSuppliers returns all supplier @@ -64,7 +64,7 @@ func (k Keeper) GetAllSuppliers(ctx context.Context) (suppliers []sharedtypes.Su for ; iterator.Valid(); iterator.Next() { var supplier sharedtypes.Supplier k.cdc.MustUnmarshal(iterator.Value(), &supplier) - k.cache.Suppliers[supplier.OperatorAddress] = &supplier + k.suppliersCache.Set(supplier.OperatorAddress, supplier) suppliers = append(suppliers, supplier) } @@ -72,7 +72,7 @@ func (k Keeper) GetAllSuppliers(ctx context.Context) (suppliers []sharedtypes.Su } func (k Keeper) ClearCache() { - k.cache.Clear() + k.suppliersCache.Clear() } // TODO_OPTIMIZE: Index suppliers by service ID diff --git a/x/supplier/types/cache.go b/x/supplier/types/cache.go deleted file mode 100644 index dcbd40fa2..000000000 --- a/x/supplier/types/cache.go +++ /dev/null @@ -1,13 +0,0 @@ -package types - -import sharedtypes "github.com/pokt-network/poktroll/x/shared/types" - -type Cache struct { - Params *Params - Suppliers map[string]*sharedtypes.Supplier -} - -func (c *Cache) Clear() { - c.Params = nil - clear(c.Suppliers) -} diff --git a/x/tokenomics/keeper/keeper.go b/x/tokenomics/keeper/keeper.go index c7ba36789..435caf8af 100644 --- a/x/tokenomics/keeper/keeper.go +++ b/x/tokenomics/keeper/keeper.go @@ -10,6 +10,7 @@ import ( "github.com/pokt-network/poktroll/pkg/client" prooftypes "github.com/pokt-network/poktroll/x/proof/types" + sharedtypes "github.com/pokt-network/poktroll/x/shared/types" tlm "github.com/pokt-network/poktroll/x/tokenomics/token_logic_module" "github.com/pokt-network/poktroll/x/tokenomics/types" ) @@ -37,7 +38,7 @@ type Keeper struct { tokenLogicModules []tlm.TokenLogicModule - cache *types.Cache + paramsCache *sharedtypes.Cache[string, types.Params] } func NewKeeper( @@ -84,7 +85,7 @@ func NewKeeper( sharedQuerier: sharedQuerier, tokenLogicModules: tokenLogicModules, - cache: &types.Cache{}, + paramsCache: sharedtypes.NewCache[string, types.Params](), } } diff --git a/x/tokenomics/keeper/params.go b/x/tokenomics/keeper/params.go index ad77b4c8f..968b5fbd6 100644 --- a/x/tokenomics/keeper/params.go +++ b/x/tokenomics/keeper/params.go @@ -10,9 +10,9 @@ import ( // GetParams get all parameters as types.Params func (k Keeper) GetParams(ctx context.Context) (params types.Params) { - if k.cache.Params != nil { + if params, found := k.paramsCache.Get(""); found { k.logger.Info("-----Tokenomics params cache hit-----") - return *k.cache.Params + return params } store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)) paramsBz := store.Get(types.ParamsKey) @@ -21,25 +21,25 @@ func (k Keeper) GetParams(ctx context.Context) (params types.Params) { } k.cdc.MustUnmarshal(paramsBz, ¶ms) - k.cache.Params = ¶ms + k.paramsCache.Set("", params) return params } // SetParams set the params func (k Keeper) SetParams(ctx context.Context, params types.Params) error { - k.cache.Params = ¶ms store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)) paramsBz, err := k.cdc.Marshal(¶ms) if err != nil { return err } store.Set(types.ParamsKey, paramsBz) + k.paramsCache.Set("", params) return nil } func (k Keeper) ClearCache() { - k.cache.Clear() + k.paramsCache.Clear() k.applicationKeeper.ClearCache() k.supplierKeeper.ClearCache() k.sharedKeeper.ClearCache() diff --git a/x/tokenomics/types/cache.go b/x/tokenomics/types/cache.go deleted file mode 100644 index cee8c58b8..000000000 --- a/x/tokenomics/types/cache.go +++ /dev/null @@ -1,9 +0,0 @@ -package types - -type Cache struct { - Params *Params -} - -func (c *Cache) Clear() { - c.Params = nil -}