@@ -823,6 +823,26 @@ func (k Keeper) appendToContractHistory(ctx context.Context, contractAddr sdk.Ac
823823 return nil
824824}
825825
826+ // appendToContractHistoryForGenesis is optimized for genesis import where
827+ // contract history is known to be empty. It writes entries sequentially starting
828+ // from position 0 without checking for existing entries.
829+ //
830+ // WARNING: Only use during genesis import via importContract(). For runtime operations,
831+ // use appendToContractHistory() which safely handles existing history.
832+ //
833+ // Performance: Avoids O(N) iteration over existing entries when state is known to be empty.
834+ // This provides significant speedup during genesis import with many contracts.
835+ func (k Keeper ) appendToContractHistoryForGenesis (ctx context.Context , contractAddr sdk.AccAddress , newEntries ... types.ContractCodeHistoryEntry ) error {
836+ store := k .storeService .OpenKVStore (ctx )
837+ for pos , e := range newEntries {
838+ key := types .GetContractCodeHistoryElementKey (contractAddr , uint64 (pos ))
839+ if err := store .Set (key , k .cdc .MustMarshal (& e )); err != nil {
840+ return err
841+ }
842+ }
843+ return nil
844+ }
845+
826846func (k Keeper ) GetContractHistory (ctx context.Context , contractAddr sdk.AccAddress ) []types.ContractCodeHistoryEntry {
827847 prefixStore := prefix .NewStore (runtime .KVStoreAdapter (k .storeService .OpenKVStore (ctx )), types .GetContractCodeHistoryElementPrefix (contractAddr ))
828848 r := make ([]types.ContractCodeHistoryEntry , 0 )
@@ -1413,6 +1433,8 @@ func (k Keeper) importAutoIncrementID(ctx context.Context, sequenceKey []byte, v
14131433 return store .Set (sequenceKey , bz )
14141434}
14151435
1436+ // importContract imports a contract instance during genesis initialization.
1437+ // Uses the optimized appendToContractHistoryForGenesis since contract history is known to be empty.
14161438func (k Keeper ) importContract (ctx context.Context , contractAddr sdk.AccAddress , c * types.ContractInfo , state []types.Model , historyEntries []types.ContractCodeHistoryEntry ) error {
14171439 if ! k .containsCodeInfo (ctx , c .CodeID ) {
14181440 return types .ErrNoSuchCodeFn (c .CodeID ).Wrapf ("code id %d" , c .CodeID )
@@ -1429,7 +1451,7 @@ func (k Keeper) importContract(ctx context.Context, contractAddr sdk.AccAddress,
14291451 return err
14301452 }
14311453
1432- err = k .appendToContractHistory (ctx , contractAddr , historyEntries ... )
1454+ err = k .appendToContractHistoryForGenesis (ctx , contractAddr , historyEntries ... )
14331455 if err != nil {
14341456 return err
14351457 }
0 commit comments