github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/cosmos-sdk/server/mock/app.go (about)

     1  package mock
     2  
     3  import (
     4  	"encoding/json"
     5  	"errors"
     6  	"fmt"
     7  	"path/filepath"
     8  
     9  	"github.com/fibonacci-chain/fbc/libs/tendermint/types"
    10  
    11  	abci "github.com/fibonacci-chain/fbc/libs/tendermint/abci/types"
    12  	"github.com/fibonacci-chain/fbc/libs/tendermint/libs/log"
    13  
    14  	bam "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/baseapp"
    15  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/codec"
    16  	sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types"
    17  )
    18  
    19  // NewApp creates a simple mock kvstore app for testing. It should work
    20  // similar to a real app. Make sure rootDir is empty before running the test,
    21  // in order to guarantee consistent results
    22  func NewApp(rootDir string, logger log.Logger) (abci.Application, error) {
    23  	db, err := sdk.NewDB("mock", filepath.Join(rootDir, "data"))
    24  	if err != nil {
    25  		return nil, err
    26  	}
    27  
    28  	// Capabilities key to access the main KVStore.
    29  	capKeyMainStore := sdk.NewKVStoreKey(bam.MainStoreKey)
    30  
    31  	// Create BaseApp.
    32  	baseApp := bam.NewBaseApp("kvstore", logger, db, decodeTx)
    33  
    34  	// Set mounts for BaseApp's MultiStore.
    35  	baseApp.MountStores(capKeyMainStore)
    36  
    37  	baseApp.SetInitChainer(InitChainer(capKeyMainStore))
    38  
    39  	// Set a handler Route.
    40  	baseApp.Router().AddRoute("kvstore", KVStoreHandler(capKeyMainStore))
    41  
    42  	// Load latest version.
    43  	if err := baseApp.LoadLatestVersion(capKeyMainStore); err != nil {
    44  		return nil, err
    45  	}
    46  
    47  	return baseApp, nil
    48  }
    49  
    50  // KVStoreHandler is a simple handler that takes kvstoreTx and writes
    51  // them to the db
    52  func KVStoreHandler(storeKey sdk.StoreKey) sdk.Handler {
    53  	return func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) {
    54  		dTx, ok := msg.(*kvstoreTx)
    55  		if !ok {
    56  			return nil, errors.New("KVStoreHandler should only receive kvstoreTx")
    57  		}
    58  
    59  		// tx is already unmarshalled
    60  		key := dTx.key
    61  		value := dTx.value
    62  
    63  		store := ctx.KVStore(storeKey)
    64  		store.Set(key, value)
    65  
    66  		return &sdk.Result{
    67  			Log: fmt.Sprintf("set %s=%s", key, value),
    68  		}, nil
    69  	}
    70  }
    71  
    72  // basic KV structure
    73  type KV struct {
    74  	Key   string `json:"key"`
    75  	Value string `json:"value"`
    76  }
    77  
    78  // What Genesis JSON is formatted as
    79  type GenesisJSON struct {
    80  	Values []KV `json:"values"`
    81  }
    82  
    83  // InitChainer returns a function that can initialize the chain
    84  // with key/value pairs
    85  func InitChainer(key sdk.StoreKey) func(sdk.Context, abci.RequestInitChain) abci.ResponseInitChain {
    86  	return func(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain {
    87  		stateJSON := req.AppStateBytes
    88  
    89  		genesisState := new(GenesisJSON)
    90  		err := json.Unmarshal(stateJSON, genesisState)
    91  		if err != nil {
    92  			panic(err) // TODO https://github.com/cosmos/cosmos-sdk/issues/468
    93  			// return sdk.ErrGenesisParse("").TraceCause(err, "")
    94  		}
    95  
    96  		for _, val := range genesisState.Values {
    97  			store := ctx.KVStore(key)
    98  			store.Set([]byte(val.Key), []byte(val.Value))
    99  		}
   100  		return abci.ResponseInitChain{}
   101  	}
   102  }
   103  
   104  // AppGenState can be passed into InitCmd, returns a static string of a few
   105  // key-values that can be parsed by InitChainer
   106  func AppGenState(_ *codec.Codec, _ types.GenesisDoc, _ []json.RawMessage) (appState json.
   107  	RawMessage, err error) {
   108  	appState = json.RawMessage(`{
   109    "values": [
   110      {
   111          "key": "hello",
   112          "value": "goodbye"
   113      },
   114      {
   115          "key": "foo",
   116          "value": "bar"
   117      }
   118    ]
   119  }`)
   120  	return
   121  }
   122  
   123  // AppGenStateEmpty returns an empty transaction state for mocking.
   124  func AppGenStateEmpty(_ *codec.Codec, _ types.GenesisDoc, _ []json.RawMessage) (
   125  	appState json.RawMessage, err error) {
   126  	appState = json.RawMessage(``)
   127  	return
   128  }