github.com/Finschia/ostracon@v1.1.5/state/helpers_test.go (about)

     1  package state_test
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"time"
     7  
     8  	abci "github.com/tendermint/tendermint/abci/types"
     9  	tmstate "github.com/tendermint/tendermint/proto/tendermint/state"
    10  	tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
    11  	dbm "github.com/tendermint/tm-db"
    12  
    13  	ocabci "github.com/Finschia/ostracon/abci/types"
    14  	"github.com/Finschia/ostracon/crypto"
    15  	"github.com/Finschia/ostracon/crypto/ed25519"
    16  	tmrand "github.com/Finschia/ostracon/libs/rand"
    17  	"github.com/Finschia/ostracon/proxy"
    18  	sm "github.com/Finschia/ostracon/state"
    19  	"github.com/Finschia/ostracon/types"
    20  	tmtime "github.com/Finschia/ostracon/types/time"
    21  )
    22  
    23  type paramsChangeTestCase struct {
    24  	height int64
    25  	params tmproto.ConsensusParams
    26  }
    27  
    28  func newTestApp() proxy.AppConns {
    29  	app := &testApp{}
    30  	cc := proxy.NewLocalClientCreator(app)
    31  	return proxy.NewAppConns(cc)
    32  }
    33  
    34  func makeAndCommitGoodBlock(
    35  	state sm.State,
    36  	height int64,
    37  	lastCommit *types.Commit,
    38  	proposerAddr []byte,
    39  	blockExec *sm.BlockExecutor,
    40  	privVals map[string]types.PrivValidator,
    41  	evidence []types.Evidence) (sm.State, types.BlockID, *types.Commit, error) {
    42  	// A good block passes
    43  	state, blockID, err := makeAndApplyGoodBlock(state,
    44  		privVals[state.Validators.SelectProposer(state.LastProofHash, height, 0).Address.String()],
    45  		height, lastCommit, proposerAddr, blockExec, evidence)
    46  	if err != nil {
    47  		return state, types.BlockID{}, nil, err
    48  	}
    49  
    50  	// Simulate a lastCommit for this block from all validators for the next height
    51  	commit, err := makeValidCommit(height, blockID, state.Validators, privVals)
    52  	if err != nil {
    53  		return state, types.BlockID{}, nil, err
    54  	}
    55  	return state, blockID, commit, nil
    56  }
    57  
    58  func makeAndApplyGoodBlock(state sm.State, privVal types.PrivValidator, height int64, lastCommit *types.Commit,
    59  	proposerAddr []byte, blockExec *sm.BlockExecutor, evidence []types.Evidence) (sm.State, types.BlockID, error) {
    60  	message := state.MakeHashMessage(0)
    61  	proof, _ := privVal.GenerateVRFProof(message)
    62  	block, _ := state.MakeBlock(height, makeTxs(height), lastCommit, evidence, proposerAddr, 0, proof)
    63  	if err := blockExec.ValidateBlock(state, 0, block); err != nil {
    64  		return state, types.BlockID{}, err
    65  	}
    66  	blockID := types.BlockID{Hash: block.Hash(),
    67  		PartSetHeader: types.PartSetHeader{Total: 3, Hash: tmrand.Bytes(32)}}
    68  	state, _, err := blockExec.ApplyBlock(state, blockID, block, nil)
    69  	if err != nil {
    70  		return state, types.BlockID{}, err
    71  	}
    72  	return state, blockID, nil
    73  }
    74  
    75  func makeValidCommit(
    76  	height int64,
    77  	blockID types.BlockID,
    78  	vals *types.ValidatorSet,
    79  	privVals map[string]types.PrivValidator,
    80  ) (*types.Commit, error) {
    81  	sigs := make([]types.CommitSig, 0)
    82  	for i := 0; i < vals.Size(); i++ {
    83  		_, val := vals.GetByIndex(int32(i))
    84  		vote, err := types.MakeVote(height, blockID, vals, privVals[val.Address.String()], chainID, time.Now())
    85  		if err != nil {
    86  			return nil, err
    87  		}
    88  		sigs = append(sigs, vote.CommitSig())
    89  	}
    90  	return types.NewCommit(height, 0, blockID, sigs), nil
    91  }
    92  
    93  // make some bogus txs
    94  func makeTxs(height int64) (txs []types.Tx) {
    95  	for i := 0; i < nTxsPerBlock; i++ {
    96  		txs = append(txs, types.Tx([]byte{byte(height), byte(i)}))
    97  	}
    98  	return txs
    99  }
   100  
   101  func makePrivVal() types.PrivValidator {
   102  	pk := ed25519.GenPrivKeyFromSecret([]byte("test private validator"))
   103  	return types.NewMockPVWithParams(pk, false, false)
   104  }
   105  
   106  func makeState(nVals, height int) (sm.State, dbm.DB, map[string]types.PrivValidator) {
   107  	vals := make([]types.GenesisValidator, nVals)
   108  	privVals := make(map[string]types.PrivValidator, nVals)
   109  	for i := 0; i < nVals; i++ {
   110  		secret := []byte(fmt.Sprintf("test%d", i))
   111  		pk := ed25519.GenPrivKeyFromSecret(secret)
   112  		valAddr := pk.PubKey().Address()
   113  		vals[i] = types.GenesisValidator{
   114  			Address: valAddr,
   115  			PubKey:  pk.PubKey(),
   116  			Power:   1000,
   117  			Name:    fmt.Sprintf("test%d", i),
   118  		}
   119  		privVals[valAddr.String()] = types.NewMockPVWithParams(pk, false, false)
   120  	}
   121  	s, _ := sm.MakeGenesisState(&types.GenesisDoc{
   122  		ChainID:    chainID,
   123  		Validators: vals,
   124  		AppHash:    nil,
   125  	})
   126  
   127  	stateDB := dbm.NewMemDB()
   128  	stateStore := sm.NewStore(stateDB, sm.StoreOptions{
   129  		DiscardABCIResponses: false,
   130  	})
   131  	if err := stateStore.Save(s); err != nil {
   132  		panic(err)
   133  	}
   134  
   135  	for i := 1; i < height; i++ {
   136  		s.LastBlockHeight++
   137  		s.LastValidators = s.Validators.Copy()
   138  		if err := stateStore.Save(s); err != nil {
   139  			panic(err)
   140  		}
   141  	}
   142  
   143  	return s, stateDB, privVals
   144  }
   145  
   146  func makeBlock(state sm.State, height int64) *types.Block {
   147  	return makeBlockWithPrivVal(state, makePrivVal(), height)
   148  }
   149  
   150  func makeBlockWithPrivVal(state sm.State, privVal types.PrivValidator, height int64) *types.Block {
   151  	message := state.MakeHashMessage(0)
   152  	proof, _ := privVal.GenerateVRFProof(message)
   153  	pubKey, _ := privVal.GetPubKey()
   154  	block, _ := state.MakeBlock(
   155  		height,
   156  		makeTxs(state.LastBlockHeight),
   157  		new(types.Commit),
   158  		nil,
   159  		pubKey.Address(),
   160  		0,
   161  		proof,
   162  	)
   163  	return block
   164  }
   165  
   166  func genValSet(size int) *types.ValidatorSet {
   167  	vals := make([]*types.Validator, size)
   168  	for i := 0; i < size; i++ {
   169  		vals[i] = types.NewValidator(ed25519.GenPrivKey().PubKey(), 10)
   170  	}
   171  	return types.NewValidatorSet(vals)
   172  }
   173  
   174  func makeHeaderPartsResponsesValPubKeyChange(
   175  	state sm.State,
   176  	pubkey crypto.PubKey,
   177  ) (types.Header, types.Entropy, types.BlockID, *tmstate.ABCIResponses) {
   178  
   179  	block := makeBlock(state, state.LastBlockHeight+1)
   180  	abciResponses := &tmstate.ABCIResponses{
   181  		BeginBlock: &abci.ResponseBeginBlock{},
   182  		EndBlock:   &abci.ResponseEndBlock{ValidatorUpdates: nil},
   183  	}
   184  	// If the pubkey is new, remove the old and add the new.
   185  	_, val := state.NextValidators.GetByIndex(0)
   186  	if !bytes.Equal(pubkey.Bytes(), val.PubKey.Bytes()) {
   187  		abciResponses.EndBlock = &abci.ResponseEndBlock{
   188  			ValidatorUpdates: []abci.ValidatorUpdate{
   189  				types.OC2PB.NewValidatorUpdate(val.PubKey, 0),
   190  				types.OC2PB.NewValidatorUpdate(pubkey, 10),
   191  			},
   192  		}
   193  	}
   194  
   195  	return block.Header, block.Entropy, types.BlockID{Hash: block.Hash(), PartSetHeader: types.PartSetHeader{}}, abciResponses
   196  }
   197  
   198  func makeHeaderPartsResponsesValPowerChange(
   199  	state sm.State,
   200  	power int64,
   201  ) (types.Header, types.Entropy, types.BlockID, *tmstate.ABCIResponses) {
   202  
   203  	block := makeBlock(state, state.LastBlockHeight+1)
   204  	abciResponses := &tmstate.ABCIResponses{
   205  		BeginBlock: &abci.ResponseBeginBlock{},
   206  		EndBlock:   &abci.ResponseEndBlock{ValidatorUpdates: nil},
   207  	}
   208  
   209  	// If the pubkey is new, remove the old and add the new.
   210  	_, val := state.NextValidators.GetByIndex(0)
   211  	if val.VotingPower != power {
   212  		abciResponses.EndBlock = &abci.ResponseEndBlock{
   213  			ValidatorUpdates: []abci.ValidatorUpdate{
   214  				types.OC2PB.NewValidatorUpdate(val.PubKey, power),
   215  			},
   216  		}
   217  	}
   218  
   219  	return block.Header, block.Entropy, types.BlockID{Hash: block.Hash(), PartSetHeader: types.PartSetHeader{}}, abciResponses
   220  }
   221  
   222  func makeHeaderPartsResponsesParams(
   223  	state sm.State,
   224  	params tmproto.ConsensusParams,
   225  ) (types.Header, types.Entropy, types.BlockID, *tmstate.ABCIResponses) {
   226  
   227  	block := makeBlock(state, state.LastBlockHeight+1)
   228  	abciResponses := &tmstate.ABCIResponses{
   229  		BeginBlock: &abci.ResponseBeginBlock{},
   230  		EndBlock:   &abci.ResponseEndBlock{ConsensusParamUpdates: types.OC2PB.ConsensusParams(&params)},
   231  	}
   232  	return block.Header, block.Entropy, types.BlockID{Hash: block.Hash(), PartSetHeader: types.PartSetHeader{}}, abciResponses
   233  }
   234  
   235  func randomGenesisDoc() *types.GenesisDoc {
   236  	pubkey := ed25519.GenPrivKey().PubKey()
   237  	return &types.GenesisDoc{
   238  		GenesisTime: tmtime.Now(),
   239  		ChainID:     "abc",
   240  		Validators: []types.GenesisValidator{
   241  			{
   242  				Address: pubkey.Address(),
   243  				PubKey:  pubkey,
   244  				Power:   10,
   245  				Name:    "myval",
   246  			},
   247  		},
   248  		ConsensusParams: types.DefaultConsensusParams(),
   249  	}
   250  }
   251  
   252  //----------------------------------------------------------------------------
   253  
   254  type testApp struct {
   255  	ocabci.BaseApplication
   256  
   257  	CommitVotes         []abci.VoteInfo
   258  	ByzantineValidators []abci.Evidence
   259  	ValidatorUpdates    []abci.ValidatorUpdate
   260  }
   261  
   262  var _ ocabci.Application = (*testApp)(nil)
   263  var TestAppVersion uint64 = 66
   264  
   265  func (app *testApp) Info(req abci.RequestInfo) (resInfo abci.ResponseInfo) {
   266  	return abci.ResponseInfo{}
   267  }
   268  
   269  func (app *testApp) BeginBlock(req ocabci.RequestBeginBlock) abci.ResponseBeginBlock {
   270  	app.CommitVotes = req.LastCommitInfo.Votes
   271  	app.ByzantineValidators = req.ByzantineValidators
   272  	return abci.ResponseBeginBlock{}
   273  }
   274  
   275  func (app *testApp) EndBlock(req abci.RequestEndBlock) abci.ResponseEndBlock {
   276  	return abci.ResponseEndBlock{
   277  		ValidatorUpdates: app.ValidatorUpdates,
   278  		ConsensusParamUpdates: &abci.ConsensusParams{
   279  			Version: &tmproto.VersionParams{
   280  				AppVersion: TestAppVersion}}}
   281  }
   282  
   283  func (app *testApp) DeliverTx(req abci.RequestDeliverTx) abci.ResponseDeliverTx {
   284  	return abci.ResponseDeliverTx{Events: []abci.Event{}}
   285  }
   286  
   287  func (app *testApp) CheckTxSync(req abci.RequestCheckTx) ocabci.ResponseCheckTx {
   288  	return ocabci.ResponseCheckTx{}
   289  }
   290  
   291  func (app *testApp) CheckTxAsync(req abci.RequestCheckTx, callback ocabci.CheckTxCallback) {
   292  	callback(ocabci.ResponseCheckTx{})
   293  }
   294  
   295  func (app *testApp) Commit() abci.ResponseCommit {
   296  	return abci.ResponseCommit{RetainHeight: 1}
   297  }
   298  
   299  func (app *testApp) Query(reqQuery abci.RequestQuery) (resQuery abci.ResponseQuery) {
   300  	return
   301  }