github.com/Finschia/finschia-sdk@v0.48.1/server/export_test.go (about)

     1  package server_test
     2  
     3  import (
     4  	"bytes"
     5  	"context"
     6  	"encoding/json"
     7  	"fmt"
     8  	"io"
     9  	"os"
    10  	"path"
    11  	"testing"
    12  
    13  	"github.com/spf13/cobra"
    14  	"github.com/stretchr/testify/require"
    15  	tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
    16  
    17  	ocabci "github.com/Finschia/ostracon/abci/types"
    18  	ostjson "github.com/Finschia/ostracon/libs/json"
    19  	"github.com/Finschia/ostracon/libs/log"
    20  	octypes "github.com/Finschia/ostracon/types"
    21  	abci "github.com/tendermint/tendermint/abci/types"
    22  	dbm "github.com/tendermint/tm-db"
    23  
    24  	"github.com/Finschia/finschia-sdk/client"
    25  	"github.com/Finschia/finschia-sdk/client/flags"
    26  	"github.com/Finschia/finschia-sdk/codec"
    27  	"github.com/Finschia/finschia-sdk/server"
    28  	"github.com/Finschia/finschia-sdk/server/types"
    29  	"github.com/Finschia/finschia-sdk/simapp"
    30  	"github.com/Finschia/finschia-sdk/types/errors"
    31  	"github.com/Finschia/finschia-sdk/x/genutil"
    32  )
    33  
    34  func TestExportCmd_ConsensusParams(t *testing.T) {
    35  	tempDir := t.TempDir()
    36  
    37  	_, ctx, genDoc, cmd := setupApp(t, tempDir)
    38  
    39  	output := &bytes.Buffer{}
    40  	cmd.SetOut(output)
    41  	cmd.SetArgs([]string{fmt.Sprintf("--%s=%s", flags.FlagHome, tempDir)})
    42  	require.NoError(t, cmd.ExecuteContext(ctx))
    43  
    44  	var exportedGenDoc octypes.GenesisDoc
    45  	err := ostjson.Unmarshal(output.Bytes(), &exportedGenDoc)
    46  	if err != nil {
    47  		t.Fatalf("error unmarshaling exported genesis doc: %s", err)
    48  	}
    49  
    50  	require.Equal(t, genDoc.ConsensusParams.Block.TimeIotaMs, exportedGenDoc.ConsensusParams.Block.TimeIotaMs)
    51  	require.Equal(t, simapp.DefaultConsensusParams.Block.MaxBytes, exportedGenDoc.ConsensusParams.Block.MaxBytes)
    52  	require.Equal(t, simapp.DefaultConsensusParams.Block.MaxGas, exportedGenDoc.ConsensusParams.Block.MaxGas)
    53  
    54  	require.Equal(t, simapp.DefaultConsensusParams.Evidence.MaxAgeDuration, exportedGenDoc.ConsensusParams.Evidence.MaxAgeDuration)
    55  	require.Equal(t, simapp.DefaultConsensusParams.Evidence.MaxAgeNumBlocks, exportedGenDoc.ConsensusParams.Evidence.MaxAgeNumBlocks)
    56  
    57  	require.Equal(t, simapp.DefaultConsensusParams.Validator.PubKeyTypes, exportedGenDoc.ConsensusParams.Validator.PubKeyTypes)
    58  }
    59  
    60  func TestExportCmd_HomeDir(t *testing.T) {
    61  	_, ctx, _, cmd := setupApp(t, t.TempDir())
    62  
    63  	cmd.SetArgs([]string{fmt.Sprintf("--%s=%s", flags.FlagHome, "foobar")})
    64  
    65  	err := cmd.ExecuteContext(ctx)
    66  	require.EqualError(t, err, "stat foobar/config/genesis.json: no such file or directory")
    67  }
    68  
    69  func TestExportCmd_Height(t *testing.T) {
    70  	testCases := []struct {
    71  		name        string
    72  		flags       []string
    73  		fastForward int64
    74  		expHeight   int64
    75  	}{
    76  		{
    77  			"should export correct height",
    78  			[]string{},
    79  			5, 6,
    80  		},
    81  		{
    82  			"should export correct height with --height",
    83  			[]string{
    84  				fmt.Sprintf("--%s=%d", server.FlagHeight, 3),
    85  			},
    86  			5, 4,
    87  		},
    88  		{
    89  			"should export height 0 with --for-zero-height",
    90  			[]string{
    91  				fmt.Sprintf("--%s=%s", server.FlagForZeroHeight, "true"),
    92  			},
    93  			2, 0,
    94  		},
    95  	}
    96  
    97  	for _, tc := range testCases {
    98  		t.Run(tc.name, func(t *testing.T) {
    99  			tempDir := t.TempDir()
   100  			app, ctx, _, cmd := setupApp(t, tempDir)
   101  
   102  			// Fast forward to block `tc.fastForward`.
   103  			for i := int64(2); i <= tc.fastForward; i++ {
   104  				app.BeginBlock(ocabci.RequestBeginBlock{Header: tmproto.Header{Height: i}})
   105  				app.Commit()
   106  			}
   107  
   108  			output := &bytes.Buffer{}
   109  			cmd.SetOut(output)
   110  			args := append(tc.flags, fmt.Sprintf("--%s=%s", flags.FlagHome, tempDir))
   111  			cmd.SetArgs(args)
   112  			require.NoError(t, cmd.ExecuteContext(ctx))
   113  
   114  			var exportedGenDoc octypes.GenesisDoc
   115  			err := ostjson.Unmarshal(output.Bytes(), &exportedGenDoc)
   116  			if err != nil {
   117  				t.Fatalf("error unmarshaling exported genesis doc: %s", err)
   118  			}
   119  
   120  			require.Equal(t, tc.expHeight, exportedGenDoc.InitialHeight)
   121  		})
   122  	}
   123  }
   124  
   125  func setupApp(t *testing.T, tempDir string) (*simapp.SimApp, context.Context, *octypes.GenesisDoc, *cobra.Command) {
   126  	if err := createConfigFolder(tempDir); err != nil {
   127  		t.Fatalf("error creating config folder: %s", err)
   128  	}
   129  
   130  	logger := log.NewOCLogger(log.NewSyncWriter(os.Stdout))
   131  	db := dbm.NewMemDB()
   132  	encCfg := simapp.MakeTestEncodingConfig()
   133  	app := simapp.NewSimApp(logger, db, nil, true, map[int64]bool{}, tempDir, 0, encCfg, simapp.EmptyAppOptions{})
   134  
   135  	serverCtx := server.NewDefaultContext()
   136  	serverCtx.Config.RootDir = tempDir
   137  
   138  	clientCtx := client.Context{}.WithCodec(app.AppCodec())
   139  	genDoc := newDefaultGenesisDoc(encCfg.Marshaler)
   140  
   141  	require.NoError(t, saveGenesisFile(genDoc, serverCtx.Config.GenesisFile()))
   142  	app.InitChain(
   143  		abci.RequestInitChain{
   144  			Validators:      []abci.ValidatorUpdate{},
   145  			ConsensusParams: simapp.DefaultConsensusParams,
   146  			AppStateBytes:   genDoc.AppState,
   147  		},
   148  	)
   149  	app.Commit()
   150  
   151  	cmd := server.ExportCmd(
   152  		func(_ log.Logger, _ dbm.DB, _ io.Writer, height int64, forZeroHeight bool, jailAllowedAddrs []string, appOptons types.AppOptions) (types.ExportedApp, error) {
   153  			encCfg := simapp.MakeTestEncodingConfig()
   154  
   155  			var simApp *simapp.SimApp
   156  			if height != -1 {
   157  				simApp = simapp.NewSimApp(logger, db, nil, false, map[int64]bool{}, "", 0, encCfg, appOptons)
   158  
   159  				if err := simApp.LoadHeight(height); err != nil {
   160  					return types.ExportedApp{}, err
   161  				}
   162  			} else {
   163  				simApp = simapp.NewSimApp(logger, db, nil, true, map[int64]bool{}, "", 0, encCfg, appOptons)
   164  			}
   165  
   166  			return simApp.ExportAppStateAndValidators(forZeroHeight, jailAllowedAddrs)
   167  		}, tempDir)
   168  
   169  	ctx := context.Background()
   170  	ctx = context.WithValue(ctx, client.ClientContextKey, &clientCtx)
   171  	ctx = context.WithValue(ctx, server.ServerContextKey, serverCtx)
   172  
   173  	return app, ctx, genDoc, cmd
   174  }
   175  
   176  func createConfigFolder(dir string) error {
   177  	return os.Mkdir(path.Join(dir, "config"), 0o700)
   178  }
   179  
   180  func newDefaultGenesisDoc(cdc codec.Codec) *octypes.GenesisDoc {
   181  	genesisState := simapp.NewDefaultGenesisState(cdc)
   182  
   183  	stateBytes, err := json.MarshalIndent(genesisState, "", "  ")
   184  	if err != nil {
   185  		panic(err)
   186  	}
   187  
   188  	genDoc := &octypes.GenesisDoc{}
   189  	genDoc.ChainID = "theChainId"
   190  	genDoc.Validators = nil
   191  	genDoc.AppState = stateBytes
   192  
   193  	return genDoc
   194  }
   195  
   196  func saveGenesisFile(genDoc *octypes.GenesisDoc, dir string) error {
   197  	err := genutil.ExportGenesisFile(genDoc, dir)
   198  	if err != nil {
   199  		return errors.Wrap(err, "error creating file")
   200  	}
   201  
   202  	return nil
   203  }